如何向类动态添加属性?

2024-09-28 22:23:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我有很多类似的类,它们都有自己的类 类属性:

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

但是所有这些很快就会变得烦人,并且需要大量的代码重复(容易出错)。在

我希望能够操作类变量并执行以下操作:

^{pr2}$

如果我可以使用继承并将参数传递给类来执行以下操作,则会更好:

^{3}$

获取作为输出“test01CONTEXTSTR”的代码。 如何根据给定的带参数的“模板”设置类的参数?在


Tags: 代码参数属性contextclassupvalsubcontextdownval
2条回答

当然,您可以手动将属性添加到类中,如下所示:

def addToClass(cls, ClassId):
    cls.Context = ClassId1+"CONTEXTSTR"
    cls.SubContext = ClassId1+"SUBCONTEXTSTR"
    cls.UpVal = ClassID+"UPVAL"
    cls.DoenVal = ClassID1+"DOWNVAL"

class NewClass(MyClass):
    ...

用法:

^{pr2}$

但如果您认为这仍然过于“手动”,并且您希望像Python这样的优秀语言应该提供更多更好的功能,那么您是对的:元类

使用元类

您可以使用元类来实现想要的行为(如果您不知道我在说什么,我建议您阅读本期文章中的最佳答案:What is a metaclass in Python?

编写元类工厂方法:

^{3}$

基于元类定义类:

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()

用法:

^{8}$
>>> class MyClass:
    def __init__(self, classid):
        self.context = "%s%s" % (classid, "CONTEXTSTR")


>>> somevar = MyClass("someid")
>>> print somevar.context
someidCONTEXTSTR
>>> 

如果你想继承一个类,那就有点不同了。从上面继续:

^{pr2}$

自动设置上下文(我想你是这么问的?),使用关键字参数:

^{3}$

在这里,我没有指定类,我只是调用它(因此有括号),关键字为我填充它。在

你这是什么意思?在

您也可以将其设置为MyClass的关键字,如果NewClass没有设置变量,它将自动赋值。我不认为你需要一个代码示例,但是如果你需要的话。在

我想这就是你想要的,如果不是的话,你需要再澄清一点对不起。在

相关问题 更多 >