<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 中是如何工作的?

        时间:2024-04-22
          <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 中是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:Python中的旧样式类和新样式类有什么区别? 下一篇:将 Pandas 的列表列拆分为多列

                  相关文章

                  <tfoot id='y0D2L'></tfoot>

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

                  1. <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'>