[英]How to dynamically add attributes to a class?
我有许多类似的类,它们都包含自己的类属性:
class MyClass1():
Context = ClassId1+"CONTEXTSTR"
SubContext = ClassId1+"SUBCONTEXTSTR"
UpVal = ClassID+"UPVAL"
DoenVal = ClassID1+"DOWNVAL"
class MyClass2():
Context = ClassId2+"CONTEXTSTR"
SubContext = ClassId2+"SUBCONTEXTSTR"
UpVal = ClassID2+"UPVAL"
DoenVal = ClassID2+"DOWNVAL"
...
但是所有这些很快变得很烦人,并且需要大量的代码重复(容易出错)。
我希望能够操纵某种class_variable并执行类似的操作:
class MyClass1():
self_cls.MakeParameters(ClassId1)
如果我可以使用继承并将参数传递给类来做类似的事情,那就更好了:
ClassID1 = "test01"
class MyClass1(BaseClass,<ClassID1>):
pass
print MyClass1.CONTEXT
获取代码“ test01CONTEXTSTR”作为输出。 如何根据具有参数的给定“模板”设置类的参数?
>>> class MyClass:
def __init__(self, classid):
self.context = "%s%s" % (classid, "CONTEXTSTR")
>>> somevar = MyClass("someid")
>>> print somevar.context
someidCONTEXTSTR
>>>
现在,如果要继承一个类,则有所不同。 从上面继续:
>>> class NewClass(MyClass):
def __init__(self, classid, secondid):
MyClass.__init__(self, classid)
self.secondcontext = "%s_%s" % (secondid, "SECONDCONTEXT")
>>> secondvar = NewClass("someid", "someotherid")
>>> secondvar.context
'someidCONTEXTSTR'
>>> secondvar.secondcontext
'someotherid_SECONDCONTEXT'
>>>
要自动设置上下文(我想问的是?),请使用关键字参数:
>>> class NewClass(MyClass):
def __init__(self, newclassid="newclassid", myclassid="myclassid"):
MyClass.__init__(self, myclassid)
self.newcontext = "%s%s" % (newclassid, " new context")
>>> NewClass().context
'myclassidCONTEXTSTR'
>>> NewClass().newcontext
'newclassid new context'
>>> NewClass(newclassid="only set this ones id").context
'myclassidCONTEXTSTR'
>>> NewClass(newclassid="only set this ones id").newcontext
'only set this ones id new context'
>>>
在这里,我没有分配课程,我只是将其命名(因此在括号中),而关键字为我填充了它。
我想这就是你的意思?
您还可以将其设置为MyClass
的关键字,如果NewClass
不设置变量,它将自动分配。 我认为您不需要为此提供代码示例,但请问是否需要。
我认为这是您所追求的,否则,您需要澄清一点抱歉。
当然,您可以像这样将属性手动添加到类中:
def addToClass(cls, ClassId):
cls.Context = ClassId1+"CONTEXTSTR"
cls.SubContext = ClassId1+"SUBCONTEXTSTR"
cls.UpVal = ClassID+"UPVAL"
cls.DoenVal = ClassID1+"DOWNVAL"
class NewClass(MyClass):
...
用法:
addToClass(NewClass, "someid")
但是,如果您认为这仍然太“手动”,并且您希望像Python这样的出色语言应该提供更多和更好的功能,那么您是对的: 元类
您可以使用元类实现所需的行为(如果您不知道我在说什么,我建议阅读本期发布的好答案: Python中的元类是什么? )
编写一个元类工厂方法:
def getMetaClass(classId):
class MyMetaClass(type):
def __new__(cls, name, bases, dct):
dct["Context"] = "%sCONTEXTSTR" % classId
dct["SubContext"] = "%sSUBCONTEXTSTR" % classId
dct["UpVal"] = "%sUPVAL" % classId
dct["DownVal"] = "%sDOWNVAL" % classId
return super(MyMetaClass, cls).__new__(cls, name, bases, dct)
return MyMetaClass
根据您的元类定义一个类:
class MyClass1():
__metaclass__ = getMetaClass("test01")
使用您的课程:
>>> A.Context
'test01CONTEXTSTR'
更新 :如果您不喜欢在每个类中都使用此__metaclass__
,则可以将其隐藏在这样的超类中(由Anders提出):
元类:
class MyMetaClass(type):
def __new__(cls, name, bases, dct):
classId = dct.get("CLASSID", "noClassId")
dct["Context"] = "%sCONTEXTSTR" % classId
dct["SubContext"] = "%sSUBCONTEXTSTR" % classId
dct["UpVal"] = "%sUPVAL" % classId
dct["DownVal"] = "%sDOWNVAL" % classId
return super(MyMetaClass, cls).__new__(cls, name, bases, dct)
类隐藏元逻辑:
class AutoContext:
__metaclass__ = getMetaClass()
用法:
class MyClass1(AutoContext):
CLASSID = "test01"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.