<bdo id='cfAUE'></bdo><ul id='cfAUE'></ul>
      <i id='cfAUE'><tr id='cfAUE'><dt id='cfAUE'><q id='cfAUE'><span id='cfAUE'><b id='cfAUE'><form id='cfAUE'><ins id='cfAUE'></ins><ul id='cfAUE'></ul><sub id='cfAUE'></sub></form><legend id='cfAUE'></legend><bdo id='cfAUE'><pre id='cfAUE'><center id='cfAUE'></center></pre></bdo></b><th id='cfAUE'></th></span></q></dt></tr></i><div id='cfAUE'><tfoot id='cfAUE'></tfoot><dl id='cfAUE'><fieldset id='cfAUE'></fieldset></dl></div>

      <tfoot id='cfAUE'></tfoot>

      <small id='cfAUE'></small><noframes id='cfAUE'>

    1. <legend id='cfAUE'><style id='cfAUE'><dir id='cfAUE'><q id='cfAUE'></q></dir></style></legend>

        @property 装饰器在 Python 中是如何工作的?

        How does the @property decorator work in Python?(@property 装饰器在 Python 中是如何工作的?)
          <bdo id='Ks52F'></bdo><ul id='Ks52F'></ul>
            <tbody id='Ks52F'></tbody>
          <i id='Ks52F'><tr id='Ks52F'><dt id='Ks52F'><q id='Ks52F'><span id='Ks52F'><b id='Ks52F'><form id='Ks52F'><ins id='Ks52F'></ins><ul id='Ks52F'></ul><sub id='Ks52F'></sub></form><legend id='Ks52F'></legend><bdo id='Ks52F'><pre id='Ks52F'><center id='Ks52F'></center></pre></bdo></b><th id='Ks52F'></th></span></q></dt></tr></i><div id='Ks52F'><tfoot id='Ks52F'></tfoot><dl id='Ks52F'><fieldset id='Ks52F'></fieldset></dl></div>

          <legend id='Ks52F'><style id='Ks52F'><dir id='Ks52F'><q id='Ks52F'></q></dir></style></legend>

          1. <small id='Ks52F'></small><noframes id='Ks52F'>

          2. <tfoot id='Ks52F'></tfoot>

                  本文介绍了@property 装饰器在 Python 中是如何工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  I would like to understand how the built-in function property works. What confuses me is that property can also be used as a decorator, but it only takes arguments when used as a built-in function and not when used as a decorator.

                  This example is from the documentation:

                  class C:
                      def __init__(self):
                          self._x = None
                  
                      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.")
                  

                  property's arguments are getx, setx, delx and a doc string.

                  In the code below property is used as a decorator. The object of it is the x function, but in the code above there is no place for an object function in the arguments.

                  class C:
                      def __init__(self):
                          self._x = None
                  
                      @property
                      def x(self):
                          """I'm the 'x' property."""
                          return self._x
                  
                      @x.setter
                      def x(self, value):
                          self._x = value
                  
                      @x.deleter
                      def x(self):
                          del self._x
                  

                  How are the x.setter and x.deleter decorators created in this case?

                  解决方案

                  The property() function returns a special descriptor object:

                  >>> property()
                  <property object at 0x10ff07940>
                  

                  It is this object that has extra methods:

                  >>> property().getter
                  <built-in method getter of property object at 0x10ff07998>
                  >>> property().setter
                  <built-in method setter of property object at 0x10ff07940>
                  >>> property().deleter
                  <built-in method deleter of property object at 0x10ff07998>
                  

                  These act as decorators too. They return a new property object:

                  >>> property().getter(None)
                  <property object at 0x10ff079f0>
                  

                  that is a copy of the old object, but with one of the functions replaced.

                  Remember, that the @decorator syntax is just syntactic sugar; the syntax:

                  @property
                  def foo(self): return self._foo
                  

                  really means the same thing as

                  def foo(self): return self._foo
                  foo = property(foo)
                  

                  so foo the function is replaced by property(foo), which we saw above is a special object. Then when you use @foo.setter(), what you are doing is call that property().setter method I showed you above, which returns a new copy of the property, but this time with the setter function replaced with the decorated method.

                  The following sequence also creates a full-on property, by using those decorator methods.

                  First we create some functions and a property object with just a getter:

                  >>> def getter(self): print('Get!')
                  ... 
                  >>> def setter(self, value): print('Set to {!r}!'.format(value))
                  ... 
                  >>> def deleter(self): print('Delete!')
                  ... 
                  >>> prop = property(getter)
                  >>> prop.fget is getter
                  True
                  >>> prop.fset is None
                  True
                  >>> prop.fdel is None
                  True
                  

                  Next we use the .setter() method to add a setter:

                  >>> prop = prop.setter(setter)
                  >>> prop.fget is getter
                  True
                  >>> prop.fset is setter
                  True
                  >>> prop.fdel is None
                  True
                  

                  Last we add a deleter with the .deleter() method:

                  >>> prop = prop.deleter(deleter)
                  >>> prop.fget is getter
                  True
                  >>> prop.fset is setter
                  True
                  >>> prop.fdel is deleter
                  True
                  

                  Last but not least, the property object acts as a descriptor object, so it has .__get__(), .__set__() and .__delete__() methods to hook into instance attribute getting, setting and deleting:

                  >>> class Foo: pass
                  ... 
                  >>> prop.__get__(Foo(), Foo)
                  Get!
                  >>> prop.__set__(Foo(), 'bar')
                  Set to 'bar'!
                  >>> prop.__delete__(Foo())
                  Delete!
                  

                  The Descriptor Howto includes a pure Python sample implementation of the property() type:

                  class Property:
                      "Emulate PyProperty_Type() in Objects/descrobject.c"
                  
                      def __init__(self, fget=None, fset=None, fdel=None, doc=None):
                          self.fget = fget
                          self.fset = fset
                          self.fdel = fdel
                          if doc is None and fget is not None:
                              doc = fget.__doc__
                          self.__doc__ = doc
                  
                      def __get__(self, obj, objtype=None):
                          if obj is None:
                              return self
                          if self.fget is None:
                              raise AttributeError("unreadable attribute")
                          return self.fget(obj)
                  
                      def __set__(self, obj, value):
                          if self.fset is None:
                              raise AttributeError("can't set attribute")
                          self.fset(obj, value)
                  
                      def __delete__(self, obj):
                          if self.fdel is None:
                              raise AttributeError("can't delete attribute")
                          self.fdel(obj)
                  
                      def getter(self, fget):
                          return type(self)(fget, self.fset, self.fdel, self.__doc__)
                  
                      def setter(self, fset):
                          return type(self)(self.fget, fset, self.fdel, self.__doc__)
                  
                      def deleter(self, fdel):
                          return type(self)(self.fget, self.fset, fdel, self.__doc__)
                  

                  这篇关于@property 装饰器在 Python 中是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Split a Pandas column of lists into multiple columns(将 Pandas 的列表列拆分为多列)
                  What is the difference between old style and new style classes in Python?(Python中的旧样式类和新样式类有什么区别?)
                  How to break out of multiple loops?(如何打破多个循环?)
                  How to put the legend out of the plot(如何将传说从情节中剔除)
                  Why is the output of my function printing out quot;Nonequot;?(为什么我的函数输出打印出“无?)
                  Difference between modes a, a+, w, w+, and r+ in built-in open function?(内置 open 函数中模式 a、a+、w、w+ 和 r+ 的区别?)
                  <tfoot id='y0D2L'></tfoot>
                    <tbody id='y0D2L'></tbody>

                    <legend id='y0D2L'><style id='y0D2L'><dir id='y0D2L'><q id='y0D2L'></q></dir></style></legend>

                      • <i id='y0D2L'><tr id='y0D2L'><dt id='y0D2L'><q id='y0D2L'><span id='y0D2L'><b id='y0D2L'><form id='y0D2L'><ins id='y0D2L'></ins><ul id='y0D2L'></ul><sub id='y0D2L'></sub></form><legend id='y0D2L'></legend><bdo id='y0D2L'><pre id='y0D2L'><center id='y0D2L'></center></pre></bdo></b><th id='y0D2L'></th></span></q></dt></tr></i><div id='y0D2L'><tfoot id='y0D2L'></tfoot><dl id='y0D2L'><fieldset id='y0D2L'></fieldset></dl></div>
                          <bdo id='y0D2L'></bdo><ul id='y0D2L'></ul>

                            <small id='y0D2L'></small><noframes id='y0D2L'>