web-dev-qa-db-fra.com

Python: propriété de la classe d'accès de la chaîne

J'ai un cours comme celui-ci:

class User:
    def __init__(self):
        self.data = []
        self.other_data = []

    def doSomething(self, source):
        // if source = 'other_data' how to access self.other_data

Je souhaite passer une chaîne pour la variable source dans doSomething et accéder au membre de la classe du même nom.

J'ai essayé getattr qui ne fonctionne que sur des fonctions (d'après ce que je peux dire), ainsi que User étendre dict et utiliser self.__getitem__, mais ça ne marche pas non plus. Quelle est la meilleure façon de procéder?

146
anon

x = getattr(self, source) fonctionnera parfaitement si source nomme AUCUN attribut de self, y compris le other_data _ dans votre exemple.

226
Alex Martelli

Une image vaut mille mots:

>>> class c:
        pass
o = c()
>>> setattr(o, "foo", "bar")
>>> o.foo
'bar'
>>> getattr(o, "foo")
'bar'
155
Robert Rossney
  • getattr(x, 'y') est équivalent à x.y
  • setattr(x, 'y', v) est équivalent à x.y = v
  • delattr(x, 'y') est équivalent à del x.y
41
Yas

Prolongeant légèrement la réponse d'Alex:

class User:
    def __init__(self):
        self.data = [1,2,3]
        self.other_data = [4,5,6]
    def doSomething(self, source):
        dataSource = getattr(self,source)
        return dataSource

A = User()
print A.doSomething("data")
print A.doSomething("other_data")

donnera:

 [1, 2, 3] 
 [4, 5, 6] 

Cependant, personnellement, je ne pense pas que ce soit un bon style - getattr vous laissera accéder à n’importe quel attribut de l’instance, y compris des éléments comme la méthode doSomething, ou même le __dict__ de l'instance. Je suggérerais plutôt de mettre en place un dictionnaire de sources de données, comme ceci:

class User:
    def __init__(self):

        self.data_sources = {
            "data": [1,2,3],
            "other_data":[4,5,6],
        }

    def doSomething(self, source):
        dataSource = self.data_sources[source]
        return dataSource

A = User()

print A.doSomething("data")
print A.doSomething("other_data")

encore céder:

 [1, 2, 3] 
 [4, 5, 6] 
4
Markus