簡體   English   中英

如何動態地向類添加屬性?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM