تعيين سمة فئة باسم معين في بيثون أثناء تحديد الفصل
سؤال
أحاول أن أفعل شيئًا كهذا:
property = 'name'
value = Thing()
class A:
setattr(A, property, value)
other_thing = 'normal attribute'
def __init__(self, etc)
#etc..........
لكن لا يمكنني العثور على الإشارة إلى الفصل للحصول على setattr
للعمل على نفس المنوال مجرد تعيين متغير في تعريف الفئة. كيف يمكنني أن أفعل هذا؟
المحلول
ستحتاج إلى استخدام metaclass لهذا:
property = 'foo'
value = 'bar'
class MC(type):
def __init__(cls, name, bases, dict):
setattr(cls, property, value)
super(MC, cls).__init__(name, bases, dict)
class C(object):
__metaclass__ = MC
print C.foo
نصائح أخرى
يمكنك أن تفعل ذلك أكثر بساطة:
class A():
vars()['key'] = 'value'
على عكس الإجابة السابقة ، يلعب هذا الحل بشكل جيد مع metaclasses الخارجية (لنماذج Django على سبيل المثال).
قد يكون هذا بسبب الفصل A
لا يتم تهيئته بالكامل عند القيام به setattr(A, p, v)
هناك.
أول شيء يجب تجربته هو مجرد تحريك settattr إلى ما بعد إغلاق class
حظر ومعرفة ما إذا كان هذا يعمل ، على سبيل المثال
class A(object):
pass
setattr (أ ، خاصية ، قيمة)
لذلك أعلم أن هذا قديم حقًا وربما يضرب حصانًا ميتًا وربما لم يكن هذا ممكنًا في ذلك الوقت ولكني أحاول حل مشكلتي.
أدركت أن هذا يمكن إنجازه دون metaclassing.
يأخذ setattr والكائن ، واسم الملحق ، والقيمة. حسنًا ، ليس الكائن هو اسم الفصل ، فهو مثيل محدد للفئة ، والتي يمكن إنجازها مع الذات.
class A(object):
def __init__(self):
self.a = 'i am a accessor'
setattr(self, 'key', 'value')
a = A()
print a.a
print a.key