Bagaimana Anda menetapkan atribut secara terprogram?

204

Misalkan saya memiliki objek python xdan string s, bagaimana cara mengatur atribut spada x? Begitu:

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

Apa keajaibannya? Tujuannya, secara tidak sengaja, adalah untuk melakukan cache panggilan x.__getattr__().

Nick
sumber

Jawaban:

288
setattr(x, attr, 'magic')

Untuk bantuan tentang itu:

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

Sunting: Namun, Anda harus mencatat (seperti yang ditunjukkan dalam komentar) bahwa Anda tidak dapat melakukan itu pada instance "murni" dari object. Tetapi kemungkinan Anda memiliki subclass objek sederhana di mana ia akan berfungsi dengan baik. Saya akan sangat mendesak OP untuk tidak pernah membuat contoh objek seperti itu.

Ali Afshar
sumber
12
Namun, hati-hati, ini tidak berfungsi dalam skenario di mana Anda membuat instance objek ().
S.Lott
3
Benar sekali, tidak. Saya dengan mudah mengabaikannya. Saya akan sangat mendesak OP untuk tidak pernah membuat contoh objek seperti itu.
Ali Afshar
2
Sayang sekali itu tidak berfungsi dalam semua kasus, karena itu akan sangat berguna, misalnya, untuk menambahkan dirtyatribut ke input pengguna ...
brice
1
@Brice: setattr bekerja di hampir semua kasus. Untuk efisiensi dan alasan lain, 'objek' diprogram sehingga Anda tidak dapat menambahkan atribut tambahan ke dalamnya. Anda dapat melakukan ini dengan kelas Anda sendiri dengan __slots__atribut.
dirkjot
4
Ini tidak berhasil intjuga. Bisakah Anda jelaskan mengapa? (Apakah ada di semua __builtin__?
Jens Timmerman
53

Biasanya, kami mendefinisikan kelas untuk ini.

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

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

Namun, Anda dapat, sampai batas tertentu, melakukan ini dengan fungsi setattrdan getattrbawaan. Namun, mereka tidak bekerja objectsecara langsung.

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

Namun, mereka bekerja pada semua jenis kelas sederhana.

class YClass( object ):
    pass

y= YClass()
setattr( y, 'myAttr', 'magic' )
y.myAttr
S.Lott
sumber
25
Adakah wawasan mengapa ini tidak bekerja dengan instance objek ()?
meawoppl
@meawoppl Anda harus menanyakan itu sebagai pertanyaan baru
Tobias Kienzler
Ditanya di sini .
jalanb
1
dapatkah saya melakukan ini dengan Modul, bukan Kelas?
bonobo
21

biarkan x menjadi objek maka Anda bisa melakukannya dengan dua cara

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