动态更改 Python Class 属性

Change Python Class attribute dynamically

我有一个 Class B 继承 Class A 和 class 属性 cls_attr。 我想在 class 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()

我尝试了几件事。我知道我可能没有找对地方,但我没有解决方案。

编辑: Classes are django admin classes

谢谢。

这似乎符合您的要求:

>>> 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'

在函数内设置即可。

编辑:更新为设置 class 属性而不是实例属性,感谢@bruno-desthuilliers。

编辑:再次更新,感谢@bruno-desthuilliers。我应该更清楚地考虑我的答案。但是你想要的在下面得到了回答。

class 属性可以在 class 或实例上读取,但您只能在 class 上设置它们(尝试在实例上设置它们只会创建一个将隐藏 class 属性的实例属性)。

如果条件在导入时已知,您可以在 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