簡體   English   中英

動態更改Python類屬性

[英]Change Python Class attribute dynamically

我有一個具有類屬性cls_attr的繼承類A的類B。 我想在類B中動態設置cls_attr。類似這樣的東西:

class A():
   cls_attr= 'value'

class B(A):

   def get_cls_val(self):
       if xxx:
          return cls_attr = 'this_value'
       return cls_attr = 'that_value'
   cls_attr = get_cls_val()

我嘗試了幾件事。 我知道我可能找不到合適的位置,但是我沒有解決辦法。

編輯:類是Django管理類

謝謝。

可以在類或實例上讀取類屬性,但是只能在類上設置它們(嘗試在實例上設置它們只會創建一個會遮蓋該類屬性的實例屬性)。

如果在導入時知道該條件,則可以在class主體中對其進行測試:

xxx = True 

Class A(object):
   cls_attr= 'value'

Class B(A):
   if xxx:
       cls_attr = 'this_value'
   else
       cls_attr = 'that_value'

現在,如果要在程序執行期間進行更改,則必須使用classmethod

class B(A):
   @classmethod
   def set_cls_attr(cls, xxx):   
       if xxx:
           cls.cls_attr = 'this_value'
       else
           cls.cls_attr = 'that_value'

或者如果您需要在測試期間訪問實例:

class B(A):
   def set_cls_attr(self, xxx):   
       cls = type(self)
       if xxx:
           cls.cls_attr = 'this_value'
       else
           cls.cls_attr = 'that_value'

如何使用classmethod並將其在子類中進行多態重寫?

class A:
    @classmethod
    def cls_attr(cls):
        return 'value'

class B(A):
    @classmethod
    def cls_attr(cls):
        if cond():
            return 'this'
        else:
            return 'that'

assert A.cls_attr() == 'value'      
cond = lambda: True
assert B.cls_attr() == 'this'
cond = lambda: False
assert B.cls_attr() == 'that'

對我來說,最簡單的解決方案是使用property裝飾器:

class B:
    @property
    def attr_name(self):
        """ do your stuff to define attr_name dynamically """
        return attr_name

這似乎可以滿足您的要求:

>>> class B(A):
     @classmethod
     def set_cls_val(cls, x):
             if x == 1:
                     cls.cls_attr = "new"

>>> c = B()
>>> c.cls_attr
'value'
>>> c.set_cls_val(B, 1)
>>> c.cls_attr
'new'
>>> B.cls_attr
'new'

只需在函數中進行設置即可。

編輯:更新以設置類屬性而不是實例屬性,謝謝@ bruno-desthuilliers。

編輯:再次更新,謝謝@ bruno-desthuilliers。 我應該更清楚地思考我的答案。 但是您想要的在下面得到了回答。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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