定义Python类实例属性
给定允许3种可能输入的类定义:定义Python类实例属性,python,class,properties,getter-setter,Python,Class,Properties,Getter Setter,给定允许3种可能输入的类定义: class FooBar(object): def __init__(self, x=None, y=None, z=None): if x is not None: self.x = x elif if y is not None: self.y = y elif if z is not None: self.z = z
class FooBar(object):
def __init__(self, x=None, y=None, z=None):
if x is not None:
self.x = x
elif if y is not None:
self.y = y
elif if z is not None:
self.z = z
else:
raise ValueError('Please supply either x,y or z')
这3个输入相互关联,比如:
x=.5*y=.25*z
这也意味着:
y=.5*z=2*x
及
z=2*y=4*x
创建FooBar()
的实例时,用户需要提供其中一个实例,而\uuuuu init\uuuuuu
会处理它
现在我想做以下几点
- 如果三个变量中的任何一个发生变化,其他变量也会随之变化
@property
def x(self):
return self._x
@x.setter
def x(self, value):
self._x = value
self._y = 2*self._x
self._z = 4*self._x
其他人:
@property
def y(self):
return self._y
@y.setter
def y(self, value):
self._y = value
self._x = .5*self._y
self._z = 2*self._y
@property
def z(self):
return self._z
@z.setter
def z(self, value):
self._z = value
self._x = .25*self._z
self._y = .5*self._z
这是正确的方法吗?我认为你让事情变得比你必须做的更复杂。如果变量是相关的,并且一个可以完全由另一个确定,则不需要存储三个变量。可以存储一个变量,并动态计算其他变量。比如:
class Foo(object):
def __init__(self, x=None, y=None, z=None):
if x is not None:
self.x = x
elif x is not None:
self.y = y
elif z is not None:
self.z = z
else:
raise ValueError('Provide an x, y, or z value.')
@property
def x(self):
return self._x
@x.setter
def x(self, value):
self._x = x
@property
def y(self):
return self._x / 2.0
@y.setter
def y(self, value):
self._x = 2 * value
@property
def z(self):
return self._x / 4.0
@z.setter
def z(self, value):
self._x = 4 * value
因此,我们只在类上存储一个\ux
属性,其余的所有getter和setter都使用\ux
属性(我们当然可以使用\uy
或\uz
)
此外,程序员可以实例化一个Foo(x=1,y=425)
,这不是很优雅。如您所见,这意味着它包含不一致性。在这种情况下,也许值得提出一个错误
通过在init模块中添加以下检查,可以确保只提供一个参数:
class Foo(object):
def __init__(self, x=None, y=None, z=None):
data = [i for i in [x, y, z] if i is not None]
if len(data) > 1:
raise ValueError('Multiple parameters provided.')
if x is not None:
self.x = x
elif x is not None:
self.y = y
elif z is not None:
self.z = z
else:
raise ValueError('Provide an x, y, or z value.')
# ...
类Foo(对象):
定义初始化(self,x=None,y=None,z=None):
数据=[i代表[x,y,z]中的i,如果i不是None]
如果len(数据)>1:
raise VALUERROR('提供了多个参数')
如果x不是无:
self.x=x
elif x不是无:
self.y=y
elif z不是无:
self.z=z
其他:
raise VALUERROR('提供x、y或z值')
#…
因此,这里我们构造了一个所有非
None
值的列表,如果有多个值,程序员提供两个或多个值,然后最好提出一个异常。如果我提供FooBar(x=1,y=1425)
?如果x=2*y
,那么self.\u y=value/2
为x
的设置者。不是值*2
。根据我的\uuuuu init\uuuuu
,x
优先,这就是原因,如果elif…。确定。我做的正好相反,你是对的。但我更担心的是实例变量的设置。为了避免“不一致”,在if
子句上添加更多的条件很简单,例如:如果x不是None,y是None,z是None:
。并对所有其他2种情况执行相同的操作,但这会变得疯狂(如果参数更多)。还有其他优雅的方法吗?好主意,是这样做的:如果sum(i在局部变量中不是None().values())>2:raisevalueerror(“…”)
。非常感谢。