Wie setzen Sie programmgesteuert ein Attribut?

204

Angenommen , ich habe ein Python - Objekt xund eine Zeichenfolge s, wie richte ich das Attribut sauf x? So:

>>> x = SomeObject()
>>> attr = 'myAttr'
>>> # magic goes here
>>> x.myAttr
'magic'

Was ist die Magie? Das Ziel dabei ist übrigens, Anrufe an zwischenzuspeichern x.__getattr__().

Nick
quelle

Antworten:

288
setattr(x, attr, 'magic')

Für Hilfe dazu:

>>> help(setattr)
Help on built-in function setattr in module __builtin__:

setattr(...)
    setattr(object, name, value)

    Set a named attribute on an object; setattr(x, 'y', v) is equivalent to
    ``x.y = v''.

Bearbeiten: Sie sollten jedoch beachten (wie in einem Kommentar erwähnt), dass Sie dies nicht mit einer "reinen" Instanz von tun können object. Aber es ist wahrscheinlich, dass Sie eine einfache Unterklasse von Objekten haben, in der es gut funktioniert. Ich möchte das OP nachdrücklich auffordern, niemals solche Objekte zu erstellen.

Ali Afshar
quelle
12
Vorsicht, dies funktioniert jedoch nicht in Ihrem Szenario, in dem Sie eine Instanz von object () erstellen.
S.Lott
3
Absolut richtig, tut es nicht. Das habe ich bequemerweise ignoriert. Ich möchte das OP nachdrücklich auffordern, niemals solche Objekte zu erstellen.
Ali Afshar
2
Verdammt schade, dass es nicht in allen Fällen funktioniert, da dies zum Beispiel sehr nützlich wäre, um das dirtyAttribut der Benutzereingabe hinzuzufügen ...
brice
1
@Brice: setattr funktioniert in fast allen Fällen. Aus Effizienz- und anderen Gründen ist 'Objekt' so programmiert, dass Sie ihm keine zusätzlichen Attribute hinzufügen können. Sie können dies mit Ihrer eigenen Klasse mit dem __slots__Attribut tun .
Dirkjot
4
Dies funktioniert auch nicht int. Kannst du erklären warum? ( __builtin__
Jens Timmerman
53

Normalerweise definieren wir dafür Klassen.

class XClass( object ):
   def __init__( self ):
       self.myAttr= None

x= XClass()
x.myAttr= 'magic'
x.myAttr

Sie können dies jedoch bis zu einem gewissen Grad mit den setattrund getattrintegrierten Funktionen tun . Sie funktionieren jedoch nicht bei Instanzen von objectdirekt.

>>> a= object()
>>> setattr( a, 'hi', 'mom' )
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'hi'

Sie arbeiten jedoch an allen Arten von einfachen Klassen.

class YClass( object ):
    pass

y= YClass()
setattr( y, 'myAttr', 'magic' )
y.myAttr
S.Lott
quelle
25
Gibt es einen Einblick, warum dies bei Instanzen von object () nicht funktioniert?
Meawoppl
@meawoppl Sie sollten das als neue Frage stellen
Tobias Kienzler
Fragte hier .
Jalanb
1
Kann ich dies mit Modulen anstelle von Klassen tun?
Bonobo
21

Sei x ein Objekt, dann kannst du es auf zwei Arten tun

x.attr_name = s 
setattr(x, 'attr_name', s)
Vijay Shanker
quelle