Python 私有属性和设置限制

Python 私有属性和设置限制,python,python-3.x,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

所以对于我的代码,代码应该打印出两条语句,分别计算向量,然后写下它们。以我的代码为例,程序应该打印出来

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)

您需要在
Vector
类中创建
get
set
方法

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)
类向量:
定义初始化(self,x,y):
自组x(x)
自我设定y(y)
定义(自我):
返回“vector:”+str(self.\uuux)+''+str(self.\uuy)
定义设置x(自身,x):
如果x<3:x=3
自
定义设置y(自,y):
如果y>=7:y=7
自我。_y=y
def get_x(自身):
返回自我
def get_y(自我):
返回自我
v1=向量(4,4)
打印(v1)
v2=向量(v1.get_x()/2,v1.get_y()*2)
打印(v2)
我添加了一些方法来完成实现

  • \uuuu str\uuuu
    返回要显示为类的
    字符串
    对象
    string
    by
    print(v1)
    您编码的内容
  • get_x
    get_y
    运行时返回
    private
    属性值
    v1.get_x()
    v1.get_y()
  • 最后,我将
    \uuu set\ux(x)
    \uu set\uy(y)
    设置为
    私有
    只能在构造函数中初始化

  • 关于双下划线。似乎它能使它成为私人的。我试着做个测试。也许这是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'
    
    class test_priv():
    定义初始化(self,x,y):
    自
    自我。_y=y
    def显示变量(自身):
    打印(self.\uux,self.\uy)
    p=测试优先级(1,2)
    p、 showvars()
    打印(p.\uux)
    $python test.py
    1 2
    回溯(最近一次呼叫最后一次):
    文件“acid.py”,第12行,在
    打印(p.\uux)
    AttributeError:“test_priv”对象没有属性“\uux”
    
    在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)
    
    类向量:
    定义初始化(self,x,y):
    自我。x=x
    自我。_y=y
    @财产
    def x(自我):
    返回自我
    @x、 塞特
    def x(自身,值):
    如果值<3:
    提升值错误('x必须大于3')
    self._x=值
    @财产
    定义y(自我):
    回归自我
    @y、 塞特
    定义y(自身,值):
    如果值>7:
    提升值错误('y必须小于7')
    self._y=值
    定义报告(自我):
    返回f'Vector(x={self.x},y={self.y})'
    v1=向量(4,4)
    打印(v1)
    v2=向量(v1.x/2,v1.y*2)
    打印(v2)
    
    关于原始代码的注释:

    • 单个下划线是“private”变量的典型标记。Python并没有真正的私有变量,所以这纯粹是一种约定。任何阅读源代码的人都知道他们可以访问
      x
      的底层值,就像
      v1.\ux
      。双下划线确实有其含义,但它的用途不同。有关更多详细信息,请参阅
    • 编写
      get\u foo
      方法是不惯用的。相反,您应该使用
      @属性
      装饰器(请参阅)
      @property
      允许您自定义“属性访问”
    • 您需要将一些输入传递到
      \uuuu init\uuu
    • 您可以
      打印(v1)
      ,但是由于您没有定义
      \uuuuu str\uuuuuuuu
      \uuuuu repr\uuuuuu
      ,这将只打印类似
      的内容,这不是很有用

    我认为公约只是一个下划线,但已经有一段时间了。这只是一个约定,因为没有一个属性是真正私有的。如果要用v1=Vector(4,4)实例化类,则初始化函数没有意义,因为它需要参数。应该是uuu init_uuuu(self,x,y)是的,错过了,哈哈,谢谢提醒。我认为它只有两个下划线才是私有的,只能在类本身中访问。Python不具有私有性…一个或多个下划线将从工具提示下拉列表中排除变量或函数,并将其从
    import*
    调用中删除,但在Python中没有任何东西是私有的。您只需使用
    打印(p.uu dict_uuu[''''u test_priv_uux'])
    即可。这称为“名称篡改”。看见