动态更改 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
我有一个 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