Comment accéder dynamiquement aux propriétés de classe en Python?

Disons que je crée une instance d'une classe et que je veux attribuer des valeurs à ses propriétés publiques. Habituellement, cela se ferait comme ceci:

class MyClass:
    def __init__(self):
        self.name = None
        self.text = None

myclass = MyClass()
myclass.name = 'My name'

Mais, que se passe - t-il si une fonction d'écriture qui prend une classe comme paramètre et je voudrais assigner des valeurs aux propriétés publiques de cette classe dynamiquement-c'est-à-dire via des variables et des boucles (sans savoir combien il y en a ou comment ils sont appelés.)

L'évidence serait:

myclass = MyClass()
myclass['name'] = "My name"

Mais ça ne marche pas.

Des idées?

22
demandé sur Honza Pokorny 2010-03-11 16:35:10

3 réponses

setattr(my_class_instance, 'attr_name', attr_value)
36
répondu shylent 2010-03-11 13:36:50

Après avoir lu la syntaxe rejetée pour L'accès aux attributs dynamiques , j'utilise une classe mixin fournissant un accès de style Dictionnaire aux attributs d'un objet :

class MyClass:
    def __init__(self):
        self.name = None
        self.text = None
    def __getitem__(self, name):
        return getattr(self, name)
    def __setitem__(self, name, value):
        return setattr(self, name, value)
    def __delitem__(self, name):
        return delattr(self, name)
    def __contains__(self, name):
        return hasattr(self, name)

Tout en étant capable de définir des attributs directement:

myclass = MyClass()
myclass.name = "foo"
myclass.text = "bar"

Il est alors possible de les définir dynamiquement :

for attr in ('name', 'text'):
    myclass[attr] = confirm(attr, default=myclass[attr])
7
répondu r2rien 2015-03-08 15:48:32

Utiliser dir avec setattr devrait faire le travail

class MyClass:
  def __init__(self):
    self.name = None
    self.text = None

myclass = MyClass()
myclass.name = 'My name'

for prop in dir(myclass):
    print '%s:%s'%(prop,getattr(myclass,prop))

print

for prop in dir(myclass):
    if prop[:2]!='__' and prop[-2:]!='__':
        print prop[-2:]
        setattr(myclass,prop,"Foo Bar")

for prop in dir(myclass):
    print '%s:%s'%(prop,getattr(myclass,prop))    

Mais attention car ce code définit également les propriétés '__doc__', '__init__', '__module__' sur "Foo Bar". Vous devrez donc prendre soin d'éviter certaines choses qui vous sont données par dir (en particulier celles qui commencent et se terminent par __ doubles traits de soulignement).

0
répondu Pratik Deoghare 2010-03-11 14:23:22