私有属性和设置限制

时间:2019-06-15 02:22:02

标签: python python-3.x

因此对于我的代码,该代码应打印出两个语句,分别计算向量并记下两个向量。以我的代码为例,程序应打印出

Vector: x=4, y=4
Vector: x=3, y=7 

但是,我在使用私有属性创建类时遇到了麻烦,并且将x的限制必须大于3,并且y不能大于7。将双下划线设为私有是否正确?

class Vector:
    def __init__(self):
        self.__x = 4
        self.__y =4


v1=Vector(4,4)
print(v1)
v2=Vector(v1.get_x()/2,v1.get_y()*2)
print(v2)

3 个答案:

答案 0 :(得分:2)

在Python中惯用的方式是这样的:

class Vector:
    def __init__(self, x, y):
        self._x = x
        self._y = y

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, value):
        if value < 3:
            raise ValueError('x must be greater than 3')

        self._x = value

    @property
    def y(self):
        return self._y

    @y.setter
    def y(self, value):
        if value > 7:
            raise ValueError('y must be less than 7')

        self._y = value

    def __repr__(self):
        return f'Vector(x = {self.x}, y = {self.y})'

v1 = Vector(4, 4)
print(v1)
v2 = Vector(v1.x / 2, v1.y * 2)
print(v2)

关于原始代码的注释:

  • 单个下划线是“专用”变量的典型标记。 Python确实没有私有变量,因此这纯粹是一个约定。任何阅读源代码的人都会知道,他们可以像x一样访问v1._x的基础值。双下划线确实有其含义,但这是出于不同的目的。有关更多详细信息,请参见https://docs.python.org/3/tutorial/classes.html#private-variables
  • 编写get_foo方法不是惯用的。相反,您应该使用@property装饰器(请参见https://docs.python.org/3/library/functions.html?highlight=property#property)。 @property可让您自定义“属性访问”。
  • 您需要将一些输入传递到__init__中。
  • print(v1),但是由于您没有定义__str____repr__,因此只会打印类似<__main__.Vector object at 0x0000019CA15D36A0>的内容,并没有太大用处。
  • li>

答案 1 :(得分:1)

您需要在get类中创建setVector方法。

class Vector:
    def __init__(self, x, y):
        self.__set_x(x)
        self.__set_y(y)

    def __str__ (self):
        return 'vector : '+str(self.__x)+' '+str(self.__y)

    def __set_x(self, x):
        if x < 3: x = 3
        self.__x = x

    def __set_y(self, y):
        if y >= 7: y = 7
        self.__y = y

    def get_x(self):
        return self.__x

    def get_y(self):
        return self.__y


v1=Vector(4,4)
print(v1)
v2=Vector(v1.get_x()/2,v1.get_y()*2)
print(v2)

我添加了一些方法来完成实现。

  1. __str__返回string要显示的对象,作为 string print(v1)的编码范围。
  2. get_xget_y在运行时返回private属性值 v1.get_x()v1.get_y()
  3. 最后,我将__set_x(x)__set_y(y)设为private 只能在构造函数中初始化。

答案 2 :(得分:0)

关于双下划线。似乎可以使其私有化。我尝试了它作为测试。也许这是对Python的一些更新版本,而不是我最初研究的版本。

class test_priv():
    def __init__(self, x, y):
        self.__x = x
        self.__y = y

    def showvars(self):
        print(self.__x, self.__y)

p = test_priv(1,2)

p.showvars()
print(p.__x)


$ python test.py
1 2
Traceback (most recent call last):
  File "acid.py", line 12, in <module>
    print(p.__x)
AttributeError: 'test_priv' object has no attribute '__x'