Como você define programaticamente um atributo?

204

Suponha que eu tenha um objeto python xe uma strings , como faço para definir o atributo sem x? Assim:

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

Qual é a mágica? O objetivo disso, aliás, é armazenar em cache as chamadas parax.__getattr__() .

usuario
fonte

Respostas:

288
setattr(x, attr, 'magic')

Para obter ajuda:

>>> 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''.

Editar: No entanto, você deve observar (como indicado em um comentário) que não pode fazer isso em uma instância "pura" de object. Mas é provável que você tenha uma subclasse simples de objeto em que funcione bem. Eu recomendaria fortemente que o OP nunca fizesse instâncias de objetos como esse.

Ali Afshar
fonte
12
Cuidado, no entanto, isso não funciona no seu cenário em que você está criando uma instância de object ().
S.Lott
3
Absolutamente certo, não. Eu convenientemente ignorei isso. Eu recomendaria fortemente que o OP nunca fizesse instâncias de objetos como esse.
1111 Ali Ali Afshar
2
Que pena que não funciona em todos os casos, pois isso seria realmente útil, por exemplo, para adicionar o dirtyatributo à entrada do usuário ...
brice
1
@Brice: setattr funciona em quase todos os casos. Por eficiência e outros motivos, 'objeto' é programado para que você não possa adicionar atributos extras a ele. Você pode fazer isso com sua própria classe com o __slots__atributo
dirkjot
4
Isso também não funciona int. Você pode explicar o porquê? (está em tudo __builtin__?
Jens Timmerman
53

Geralmente, definimos classes para isso.

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

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

No entanto, você pode, até certo ponto, fazer isso com as funções setattre getattrbuilt-in. No entanto, eles não funcionam objectdiretamente em instâncias .

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

No entanto, eles trabalham em todos os tipos de classes simples.

class YClass( object ):
    pass

y= YClass()
setattr( y, 'myAttr', 'magic' )
y.myAttr
S.Lott
fonte
25
Alguma idéia de por que isso não funciona com instâncias de object ()?
precisa saber é o seguinte
@meawoppl Você deve fazer isso como uma nova pergunta
Tobias KIENZLER
Perguntou aqui .
Jalanb 22/04
1
posso fazer isso com módulos, em vez de classes?
bonobo
21

Seja x um objeto, então você pode fazê-lo de duas maneiras

x.attr_name = s 
setattr(x, 'attr_name', s)
vijay shanker
fonte