Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:如何使属性私有化来阻止程序进入无限循环?(私人v/s公共属性)_Python_Python 3.x_Class_Oop_Private - Fatal编程技术网

Python:如何使属性私有化来阻止程序进入无限循环?(私人v/s公共属性)

Python:如何使属性私有化来阻止程序进入无限循环?(私人v/s公共属性),python,python-3.x,class,oop,private,Python,Python 3.x,Class,Oop,Private,我对python中的面向对象概念很幼稚。在阅读本文中的OOP概念时,我遇到了一个例子 class P1: def __init__(self,x): self.x = x @property def x(self): return self.__x @x.setter def x(self, x): if x < 0: self.__x = 0 elif x

我对python中的面向对象概念很幼稚。在阅读本文中的OOP概念时,我遇到了一个例子

class P1:

    def __init__(self,x):
        self.x = x

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

    @x.setter
    def x(self, x):
        if x < 0:
            self.__x = 0
        elif x > 1000:
            self.__x = 1000
        else:
            self.__x = x

e = P(x = 2100)
f = e.x*2

print(f)
2000
似乎我的程序首先调用了init方法,然后它从setter区域3setter区域6连续来回运行。 有人能解释一下吗

  • 幕后发生了什么?程序是如何运行的

  • 为什么要在这里设置magic私有属性,这样程序就不会运行在无限循环中

  • @property和@x.setter在这里是如何相互关联的?我不能在不写@property的情况下写@setter吗

  • 我知道这些都是基本问题,但我浏览了太多的网上资料,没有找到更好的答案

    “为什么要在这里设置魔法私有属性,使程序 没有陷入无限循环”

    实际上,这不是一个使用双下划线名称的好地方。我喜欢那个教程,除了那个细节。您可以使用一个下划线或任何有效的python标识符(属性占用的标识符除外),您将看到相同的效果

    属性是实现的对象。对于常见的描述符用例,它是一个方便的描述符。但是我们可以创建自己的描述符类型

    从根本上说,描述符是实现
    \uuuuu get\uuuuu
    \uuuu set\uuuuu
    \uuu delete\uuuu
    任意组合的任何python类型

    当您执行
    某些\u对象时,将调用这些属性。某些\u属性
    某些\u对象。某些\u属性=值
    ,以及
    删除某些\u对象。某些\u属性
    其中
    某些\u属性
    某些\u对象上的描述符。\uu类

    <>所以,考虑一个具体的例子:

    >>> class Foo:
    ...     def __get__(self, obj, objtype):
    ...         print('inside Foo.__get__')
    ...         return 42
    ...
    >>> class Bar:
    ...     foo = Foo()
    ...
    >>> bar = Bar()
    >>> bar.foo
    inside Foo.__get__
    42
    
    描述符截取属性访问、修改和删除类实例(该类将描述符作为属性),以允许各种有趣的内容

    请注意,描述符属于以下类:

    >>> vars(bar)
    {}
    >>> vars(Bar)
    mappingproxy({'__module__': '__main__', 'foo': <__main__.Foo object at 0x1025272e8>, '__dict__': <attribute '__dict__' of 'Bar' objects>, '__weakref__': <attribute '__weakref__' of 'Bar' objects>, '__doc__': None})
    
    但是我们可以控制它,我们可以实现

    >>> class Foo:
    ...    def __get__(self, obj, objtype):
    ...       return 42
    ...    def __set__(self, obj, val):
    ...       print('nah-ah-ah')
    ...
    ...
    >>> class Bar:
    ...     foo = Foo()
    ...
    >>> bar = Bar()
    >>> bar.foo
    42
    >>> bar.foo = 99
    nah-ah-ah
    >>> bar.foo
    42
    
    属性
    对象只允许您提供在使用
    属性时将被委托的函数。\uuuuu获取\uuuuuuuu
    属性。\uuuuuu设置\uuuuuuuuuu
    属性。docstrings的信息量很大,只需在python shell中使用
    帮助(属性)

    class property(object)
     |  property(fget=None, fset=None, fdel=None, doc=None)
     |
     |  Property attribute.
     |
     |    fget
     |      function to be used for getting an attribute value
     |    fset
     |      function to be used for setting an attribute value
     |    fdel
     |      function to be used for del'ing an attribute
     |    doc
     |      docstring
     |
     |  Typical use is to define a managed attribute x:
     |
     |  class C(object):
     |      def getx(self): return self._x
     |      def setx(self, value): self._x = value
     |      def delx(self): del self._x
     |      x = property(getx, setx, delx, "I'm the 'x' property.")
     |
     |  Decorators make defining new properties or modifying existing ones easy:
     |
     |  class C(object):
     |      @property
     |      def x(self):
     |          "I am the 'x' property."
     |          return self._x
     |      @x.setter
     |      def x(self, value):
     |          self._x = value
     |      @x.deleter
     |      def x(self):
     |          del self._x
    
    因此,无论您用
    @property.setter
    装饰什么,您都可以想象get被传递到
    属性(fset=)
    。现在,每当您的实例尝试设置
    x.some\u attribute=value
    时,其中
    的某个属性
    类x:
    上的一个属性,调用
    属性时,您可以想象它会被调用
    x.some\u attribute=value
    转换为
    x.some\u属性

    因此,为了找到问题的关键,为什么无限递归,因为使用
    obj.x=val
    ,其中
    .x
    是一个属性,将调用
    fset
    ,但是在fset中使用
    obj.x=val
    ,并且
    fset
    会再次被调用,这是隐藏的递归

    @decorator
    语法是为了方便起见,始终首先接受getter,但您可以使用长格式方式仅提供setter:

    >>> class Weird:
    ...    def setx(self, value):
    ...       self._x = value
    ...    x = property(fset=setx)
    ...
    >>> w = Weird()
    >>> w.x = 'foo'
    >>> w.x
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: unreadable attribute
    
    >>类:
    ...    def setx(自身,值):
    ...       self._x=值
    ...    x=属性(fset=setx)
    ...
    >>>w=奇怪的()
    >>>w.x=‘foo’
    >>>w.x
    回溯(最近一次呼叫最后一次):
    文件“”,第1行,在
    AttributeError:无法读取的属性
    
    我强烈建议你阅读这本书。扰流板警报、
    classmethod
    staticmethod
    都是描述符,Python如何神奇地将实例传递给方法也是描述符(也就是说,所有函数对象都是描述符,当被类上的实例访问时,
    \uuu get\uu
    方法将实例作为第一个参数传递给函数本身。)它还显示了所有这些内容的Python实现,包括如何在纯Python中实现
    属性

    “为什么要在这里设置魔法私有属性,使程序 没有陷入无限循环”

    实际上,这不是一个使用双下划线名称混乱的好地方。除了一个细节之外,我喜欢那个教程。您可以使用一个下划线,或者任何有效的python标识符(除了属性占用的标识符),您将看到相同的效果

    属性是一个实现的对象。对于常见的描述符用例,它是一个方便的描述符。但是我们可以创建自己的描述符类型

    从根本上说,描述符是实现
    \uuuuu get\uuuuu
    \uuuu set\uuuuu
    \uuu delete\uuuu
    任意组合的任何python类型

    当您执行
    某些\u对象时,将调用这些属性。某些\u属性
    某些\u对象。某些\u属性=值
    ,以及
    删除某些\u对象。某些\u属性
    其中
    某些\u属性
    某些\u对象上的描述符。\uu类

    <>所以,考虑一个具体的例子:

    >>> class Foo:
    ...     def __get__(self, obj, objtype):
    ...         print('inside Foo.__get__')
    ...         return 42
    ...
    >>> class Bar:
    ...     foo = Foo()
    ...
    >>> bar = Bar()
    >>> bar.foo
    inside Foo.__get__
    42
    
    描述符截取属性访问、修改和删除类实例(该类将描述符作为属性),以允许各种有趣的内容

    请注意,描述符属于以下类:

    >>> vars(bar)
    {}
    >>> vars(Bar)
    mappingproxy({'__module__': '__main__', 'foo': <__main__.Foo object at 0x1025272e8>, '__dict__': <attribute '__dict__' of 'Bar' objects>, '__weakref__': <attribute '__weakref__' of 'Bar' objects>, '__doc__': None})
    
    但是我们可以控制它,我们可以实现

    >>> class Foo:
    ...    def __get__(self, obj, objtype):
    ...       return 42
    ...    def __set__(self, obj, val):
    ...       print('nah-ah-ah')
    ...
    ...
    >>> class Bar:
    ...     foo = Foo()
    ...
    >>> bar = Bar()
    >>> bar.foo
    42
    >>> bar.foo = 99
    nah-ah-ah
    >>> bar.foo
    42
    
    属性
    对象只允许您提供在使用
    属性时将被委托的函数。
    属性。
    属性。
    设置属性。
    属性。
    删除属性。
    文档字符串信息量很大,只需在python shell中使用
    帮助(属性)

    class property(object)
     |  property(fget=None, fset=None, fdel=None, doc=None)
     |
     |  Property attribute.
     |
     |    fget
     |      function to be used for getting an attribute value
     |    fset
     |      function to be used for setting an attribute value
     |    fdel
     |      function to be used for del'ing an attribute
     |    doc
     |      docstring
     |
     |  Typical use is to define a managed attribute x:
     |
     |  class C(object):
     |      def getx(self): return self._x
     |      def setx(self, value): self._x = value
     |      def delx(self): del self._x
     |      x = property(getx, setx, delx, "I'm the 'x' property.")
     |
     |  Decorators make defining new properties or modifying existing ones easy:
     |
     |  class C(object):
     |      @property
     |      def x(self):
     |          "I am the 'x' property."
     |          return self._x
     |      @x.setter
     |      def x(self, value):
     |          self._x = value
     |      @x.deleter
     |      def x(self):
     |          del self._x
    
    因此,无论您用
    @property.setter
    装饰什么,您都可以想象get传递给