คุณจะตั้งค่าคุณลักษณะทางโปรแกรมได้อย่างไร


204

สมมติว่าฉันมีวัตถุหลามxและสตริงsฉันจะตั้งค่าแอตทริบิวต์sบนx? ดังนั้น:

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

ความมหัศจรรย์คืออะไร? x.__getattr__()เป้าหมายของการนี้บังเอิญเป็นสายแคช

คำตอบ:


288
setattr(x, attr, 'magic')

สำหรับความช่วยเหลือเกี่ยวกับมัน:

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

แก้ไข: แต่คุณควรทราบ (ตามที่ออกมาชี้ในความคิดเห็น) ที่คุณไม่สามารถทำแบบนั้นกับอินสแตนซ์ "บริสุทธิ์" objectของ แต่ดูเหมือนว่าคุณจะมีคลาสย่อยของวัตถุที่จะทำงานได้ดี ฉันขอเรียกร้องให้ OP ไม่ทำวัตถุอย่างนั้น


12
อย่างไรก็ตามระวังสิ่งนี้ไม่ทำงานในสถานการณ์ที่คุณกำลังสร้างตัวอย่างของวัตถุ ()
S.Lott

3
ถูกต้องแน่นอนมันไม่ได้ ฉันไม่สนใจสิ่งนั้นอย่างสะดวก ฉันขอเรียกร้องให้ OP ไม่ทำวัตถุอย่างนั้น
Ali Afshar

2
ประณามความอัปยศมันไม่ทำงานในทุกกรณีเช่นนั้นจะมีประโยชน์จริง ๆ เช่นการเพิ่มแอdirtyททริบิวให้ผู้ใช้ป้อน ...
ราคา

1
@ ราคา: setattr ทำงานได้ในเกือบทุกกรณี เพื่อประสิทธิภาพและเหตุผลอื่น ๆ 'วัตถุ' ได้รับการตั้งโปรแกรมเพื่อให้คุณไม่สามารถเพิ่มคุณสมบัติพิเศษลงไปได้ คุณสามารถทำสิ่งนี้กับคลาสของคุณเองด้วย__slots__คุณสมบัติ
dirkjot

4
สิ่งนี้ใช้ไม่ได้intเช่นกัน คุณอธิบายได้ไหม (มันอยู่กับทุกคน__builtin__เหรอ
Jens Timmerman

53

โดยปกติเราจะกำหนดคลาสสำหรับสิ่งนี้

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

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

แต่คุณสามารถที่มีขอบเขตการทำเช่นนี้ด้วยsetattrและgetattrในตัวฟังก์ชั่น อย่างไรก็ตามพวกเขาไม่ทำงานในกรณีของobjectโดยตรง

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

อย่างไรก็ตามพวกเขาทำงานกับคลาสที่เรียบง่ายทุกชนิด

class YClass( object ):
    pass

y= YClass()
setattr( y, 'myAttr', 'magic' )
y.myAttr

25
ข้อมูลเชิงลึกเกี่ยวกับสาเหตุที่ไม่สามารถทำงานกับอินสแตนซ์ของวัตถุ ()?
meawoppl

@meawoppl คุณควรถามว่าเป็นคำถามใหม่
Tobias Kienzler

ถามนี่
jalanb

1
ฉันสามารถทำสิ่งนี้กับโมดูลแทนที่จะเป็น Classes ได้หรือไม่
bonobo

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.