定义Python类实例属性

问题描述 投票:1回答:1

给定一个允许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
        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()的实例时,用户需要提供其中一个,__init__负责处理它。

现在我想做以下事情

  • 如果3个变量中的任何一个被更改,则其他变量会根据关系发生变化。

为了实现这一点,我做了:

@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

这是正确的方法吗?

python class properties getter-setter
1个回答
2
投票

我认为你让这比你更复杂。如果变量是相关的,并且可以完全由另一个确定,则不需要存储三个变量。您可以存储一个变量,并动态计算其他变量。喜欢:

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

因此,我们只在类上存储_x属性,并且所有其余的getter和setter都使用_x属性(我们当然可以使用_y_z)。

此外,一些不太优雅的东西是程序员可以实例化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.')

    # ...

因此,我们构造了所有非None值的列表,如果有多个值,程序员提供了两个或更多值,那么最好引发异常。

© www.soinside.com 2019 - 2024. All rights reserved.