繁体   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