Python: 如何根据同一实例的另一个属性的布尔值自动更改实例的属性?
Python: How to automatically change an attribute of an instance depending on the boolean value of another attribute of the same instance?
假设我有 class 和它的一个实例
class MyClass:
a = False
b = [0,1,2]
MCi = MyClass()
显然 MCi.a
给出 False
而 MCi.b
给出 [0,1,2]
.
我想要的是,如果我设置MCi.a = True
,MCi.b
的值变为[0,1,2,3,4,5]
。当我退回 MCi.a = False
.
时,我希望它回到 [0,1,2]
换句话说,MCi.a
应该指定 MCi.b
,而不必从外部设置后者的属性值。
我该怎么做?
这个问题和我之前问的非常接近,但是我没有足够仔细地表述我的问题,所以那里提供的解决方案实际上并不是我需要的。不过,使用 __setattr__()
的想法可能是一个好的开始。但到目前为止我失败了。
在这种情况下,我会使用一种方法来设置布尔值。这样你就永远不会直接从外部设置布尔实例变量,而是调用一个方法来改变它。如果你想隐藏,实际上使用了一个方法,你可以将它定义为 属性。这看起来像:
class MyClass:
# prefix the instance variables with an underscore
# as a convention to indicate they are private
_a = False
_b = [0,1,2]
# define accessors
@property
def a(self):
return self._a
@a.setter
def a(self, bool):
self._a= bool
if bool is True:
self._b= [0,1,2,3,4,5]
else:
self._b= [0,1,2]
# define accessors
@property
def b(self):
return self._b
现在我们可以测试一下:
o= MyClass()
print(f'{o._a}, {o._b}')
o.a=True
print(f'{o._a}, {o._b}')
o.a=False
print(f'{o._a}, {o._b}')
print(o.b)
o.b=[12,3]
这会打印:
False, [0, 1, 2]
True, [0, 1, 2, 3, 4, 5]
False, [0, 1, 2]
[0, 1, 2]
Traceback (most recent call last):
File "<ipython-input-14-1e243ad0d3ed>", line 8, in <module>
o.b=[12,3]
AttributeError: can't set attribute
因此您可以看到,当通过 o.a=
分配 bool 时,_b
的内容确实发生了变化,并且您可以通过使用访问 o._b
的值属性 o.b
,但您不能通过 o.b=
设置它。这只是因为我没有定义setter。如果你想拥有一个,你必须为它定义一个函数,就像在 a
.
的 setter 中一样
如果您这样定义它,您应该遵循惯例,即您不会在 class MyClass
之外的任何地方访问真实实例变量 _a
和 _b
在你的代码中。
假设我有 class 和它的一个实例
class MyClass:
a = False
b = [0,1,2]
MCi = MyClass()
显然 MCi.a
给出 False
而 MCi.b
给出 [0,1,2]
.
我想要的是,如果我设置MCi.a = True
,MCi.b
的值变为[0,1,2,3,4,5]
。当我退回 MCi.a = False
.
[0,1,2]
换句话说,MCi.a
应该指定 MCi.b
,而不必从外部设置后者的属性值。
我该怎么做?
这个问题和我之前问的__setattr__()
的想法可能是一个好的开始。但到目前为止我失败了。
在这种情况下,我会使用一种方法来设置布尔值。这样你就永远不会直接从外部设置布尔实例变量,而是调用一个方法来改变它。如果你想隐藏,实际上使用了一个方法,你可以将它定义为 属性。这看起来像:
class MyClass:
# prefix the instance variables with an underscore
# as a convention to indicate they are private
_a = False
_b = [0,1,2]
# define accessors
@property
def a(self):
return self._a
@a.setter
def a(self, bool):
self._a= bool
if bool is True:
self._b= [0,1,2,3,4,5]
else:
self._b= [0,1,2]
# define accessors
@property
def b(self):
return self._b
现在我们可以测试一下:
o= MyClass()
print(f'{o._a}, {o._b}')
o.a=True
print(f'{o._a}, {o._b}')
o.a=False
print(f'{o._a}, {o._b}')
print(o.b)
o.b=[12,3]
这会打印:
False, [0, 1, 2]
True, [0, 1, 2, 3, 4, 5]
False, [0, 1, 2]
[0, 1, 2]
Traceback (most recent call last):
File "<ipython-input-14-1e243ad0d3ed>", line 8, in <module>
o.b=[12,3]
AttributeError: can't set attribute
因此您可以看到,当通过 o.a=
分配 bool 时,_b
的内容确实发生了变化,并且您可以通过使用访问 o._b
的值属性 o.b
,但您不能通过 o.b=
设置它。这只是因为我没有定义setter。如果你想拥有一个,你必须为它定义一个函数,就像在 a
.
如果您这样定义它,您应该遵循惯例,即您不会在 class MyClass
之外的任何地方访问真实实例变量 _a
和 _b
在你的代码中。