BrightXiong 发表于 2023-4-1 19:38:15

类和对象-property

>>> #property()函数,该函数用于返回一个property属性对象,使之成为“托管属性”,全权代理该类中的私有属性,从而对其进行访问或修改,
        实现起来比用“魔法方法三件套”(__getattr__()、__setattr__()、__delattr__())更简单。
        此外,作为装饰器也是property()函数的经典应用,可以轻松创建只读属性,因为property()的第一个参数正是获取私有属性的函数。
        property属性对象还提供了getter()、setter()、deleter()三个方法,对应该函数的三个参数接口,使用相应方法作为装饰器殊途同归。

>>> #class property(fget=None,fset=None,fdel=None,doc=None)   P159   Build-in Class
>>> #property()函数用于返回一个property属性对象
>>> class C:
...         def __init__(self):
...                 self._x = 250
...         def getx(self):
...                 return self._x
...         def setx(self, value):
...                 self._x = value
...         def delx(self):
...                 del self._x
...         x = property(getx, setx, delx)
...
>>> c = C()
>>> print(c.x)
250
>>> c.x = 520
>>> print(c.__dict__)
{'_x': 520}
>>> del c.x
>>> print(c.__dict__)
{}

>>> #利用__getattr__()、__setattr__()、__delattr__()实现相同目的
>>> class D:
...         def __init__(self):
...                 self._x = 250
...         def __getattr__(self, item):
...                 if item == 'x':
...                         return self._x
...                 else:
...                         super().__getattr__(item)
...         def __setattr__(self, key, value):
...                 if key == 'x':
...                         super().__setattr__('_x', value)
...                 else:
...                         super().__setattr__(key, value)
...         def __delattr__(self, item):
...                 if item == 'x':
...                         super().__delattr__('_x')
...                 else:
...                         super().__delattr__(item)
...
>>> d = D()
>>> print(getattr(d, 'x'))
250
>>> d.x = 520
>>> print(d.__dict__)
{'_x': 520}
>>> del d.x
>>> print(d.__dict__)
{}

>>> #propert()函数第一个优点是简化类似遮遮掩掩的操作
>>> #讲property()函数做装饰器使用,会让创建只读属性工作变得极为简单
>>> class E:
...         def __init__(self):
...                 self._x = 250
...         @property
...         def x(self):
...                 return self._x
...
>>> e = E()
>>> print(e.x)
250
>>> try:
...         e.x = 520
... except AttributeError as e:
...         print(e)
...
can't set attribute

>>> #只能读取属性,不能修改,原因:吧装饰器改写成正常情况应该是
>>> class E:
...         def __init__(self):
...                 self._x = 250
...         def x(self):
...                 return self._X
...         x = property(x)#位置参数传x对应第一个参数fget
...
>>> # 所以只读。
>>> # 想要继续传入其他两个参数,property属性对象(由property函数返回,根据语法糖解析是传给了x)提供了getter、setter和deleter三个方法,这些方法对应property()函数的三个参数接口
>>> class E:
...         def __init__(self):
...                 self._x = 250
...         @property
...         def x(self):
...                 return self._x
...         @x.setter
...         def x(self, vaule):
...                 self._x = vaule
...         @x.deleter
...         def x(self):
...                 del self._X
...
>>> e = E()
>>> print(e.x)
250
>>> e.x = 520
>>> print(e.__dict__)
{'_x': 520}
>>> del e.x
>>> print(e.__dict__)
{}

Kaiser99916 发表于 2023-4-1 20:15:14

大佬

cmu052115 发表于 2023-4-3 18:01:52

{:10_266:}{:10_266:}{:10_266:}
页: [1]
查看完整版本: 类和对象-property