网络编程
位置:首页>> 网络编程>> Python编程>> Python装饰器中@property使用详解

Python装饰器中@property使用详解

作者:小朋友2D  发布时间:2022-04-22 04:46:44 

标签:python,装饰器,@property

最初的声明方式

在没有@property修饰的情况下,需要分别声明get、set、delete函数,然后初始化property类,将这些方法加载进property中

class C持有property的实例化对象x

对外表现出来C().x时,实际上是调用C()中的x(property类)中设置的fset,fget,fdel,分别对应getx,setx,delx

C真正持有的x,是self._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.")

property类 结合x = property(getx, setx, delx, "I'm the 'x' property.")与property的__init__()可以发现property接受四个参数

fget,用于获取属性值,

fset,用于设置属性值

fdel,用于删除属性

doc,属性的介绍

可以单独设置fget、fset、fdel…

x = property,x.getter(getx),x.setter(setx),x.deleter(delx)

class property(object):

def deleter(self, *args, **kwargs): # real signature unknown
       """ Descriptor to change the deleter on a property. """
       pass

def getter(self, *args, **kwargs): # real signature unknown
       """ Descriptor to change the getter on a property. """
       pass

def setter(self, *args, **kwargs): # real signature unknown
       """ Descriptor to change the setter on a property. """
       pass

def __delete__(self, *args, **kwargs): # real signature unknown
       """ Delete an attribute of instance. """
       pass

def __getattribute__(self, *args, **kwargs): # real signature unknown
       """ Return getattr(self, name). """
       pass

def __get__(self, *args, **kwargs): # real signature unknown
       """ Return an attribute of instance, which is of type owner. """
       pass

def __init__(self, fget=None, fset=None, fdel=None, doc=None): # known special case of
       pass

使用装饰器的声明方式

需要注意,装饰器只是一个python的语法糖,可以拆解成普通使用方法,如property(getx)

@property创建了一个实例x,对于def x(self)实际上是C类持有x = property(fget=x)

因此,x.setter方法指向的是property.setter,也是起到装饰器效果x.setter(x)(注意,前者x是property实例x,后者x是def x(self, value)函数),x.deleter同理

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实例化后的名字与属性名一致?

换种问法就是为什么x = property(...)

可以认为是

attributes_and_methods = {
   x.__name__: property(x), //声明C类持有property实例
   #...
}
C = type('C', (object,), attributes_and_methods)

使用装饰器的调用过程

执行C().x时,调用的是C().x(property)绑定的fget方法,用过__get__唤醒,setter、deleter同理

class property(object):

#...
   def __init__(self, fget=None, fset=None, fdel=None, doc=None):
       self.fget = fget
       self.fset = fset
       self.fdel = fdel
       ...

def __get__(self, obj, objtype=None): # real signature unknown
       if obj is None:
           return self
       if self.fget is None:
           raise AttributeError("unreadable attribute")
       return self.fget(obj)

来源:https://blog.csdn.net/ct2020129/article/details/122681130

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com