python通过property特性管理属性

发布时间:2024年01月03日

1 python通过property特性管理属性

python的property内置函数,把特定属性访问定位到get和set处理器函数,也叫做特性(Property)。

特性协议把一个特定属性的访问、设置、删除操作指向入参提供的方法,这样能够在属性访问、设置、删除时添加自动运行的代码,还可以为属性提供文档。

通过内置函数property创建特性并将其分配给类属性,可以被子类和实例继承。

一个特性管理一个单个的、特定的属性。

使用特性可以像访问属性一样调用方法。

1.1 property()创建特性

把property()内置函数的结果赋值给一个类属性来创建一个特性。

用法

property(fget=None, fset=None, fdel=None, doc=None)
#比如:
class C(object):
   def __init__(self,x):self._x = x
   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.")

描述

fget:获取属性值的函数

fset:设置属性值的函数

fdel:删除属性值的函数

doc:属性描述信息

注意:getx里面的self._x不能用self.x,因为self.x会自动调用getx,导致陷入无限循环。

访问属性时自动调用fget函数,比如C().x自动调用getx()

设置属性时自动调用fset函数,比如C().x=v自动调用setx(v)

删除属性时自动调用fdel函数,比如del C().x自动调用delx()

获取属性描述时自动获取doc的值,比如C.name.doc

示例

>>> class Person:
    def __init__(self,name):
        self._name=name
    def getName(self):
        print('获取属性值')
        return self._name
    def setName(self,value):
        print('设置属性值')
        self._name=value
    def delName(self):
        print('删除属性')
        del self._name
    name = property(getName,setName,delName,'属性描述信息')
>>> class PTPerson(Person):pass
>>> p1=PTPerson('梯阅线条')
# p1.name 访问属性name时,自动调用getName(fget)函数
>>> p1.name
获取属性值
'梯阅线条'
# p1.name=值 设置属性name时,自动调用setName(fset)函数
>>> p1.name='梯阅'
设置属性值
>>> p1.name
获取属性值
'梯阅'
# del p1.name 删除属性name时,自动调用delName(fdel)函数
>>> del p1.name
删除属性
>>> p1.name='梯阅线条'
设置属性值
>>> p1.name
获取属性值
'梯阅线条'
# PTPerson.name.__doc__ 获取属性描述时,自动获取doc的值
>>> PTPerson.name.__doc__
'属性描述信息'

1.2 装饰器创建特性

函数装饰器:

@decorator
def func(args):pass

等效于

def func(args):pass
func=decorator(func)

用法

class ClassName:
    # attribute=property(attribute),通过特性property创建属性
    @property
    def attribute(self):
        'attribute doc' # 属性描述,赋值给property()的doc入参
        return self._attribute

    # attribute=attribute.setter(attribute)
    @attribute.setter
    def attribute(self, value):
        self._attribute = value
    
    # attribute=attribute.deleter(attribute)
    @attribute.deleter
    def attribute(self):
        del self._attribute

描述

(1) 获取属性值时自动调用@property修饰的attribute()方法;

(2) 设置属性值时自动调用@attribute.setter修饰的attribute()方法;

(3) 删除属性时自动调用@attribute.deleterr修饰的attribute()方法;

(4) 创建(获取)属性用@property;

(5) 设置属性值用@属性名.setter;

(6) 删除属性用@属性名.deleter;

(7) @property装饰的方法用于创建属性,被装饰的方法名为属性名;

(8) @property创建的属性,必须返回一个值,否则无法访问该属性;

(9) @attribute.setter、@attribute.deleter的attribute必须和@property装饰的方法名attribute一致;即setter和deleter装饰器前面的attribute和@property装饰的方法名必须一致;用于区分多个属性,指明设置和修改哪个属性;

(10) @ attribute.setter和@ attribute.deleter装饰的方法名必须和和@property装饰的方法名一致;

(11) 设置、删除属性前必须先用property创建属性,否则报错;

示例

>>> class PTCircle:
    def __init__(self,r):
        self.pi=3.14
        self._r=r
        self._d=0
        self._c=0
        self._s=0
    @property
    def r(self):
        'doc:定义半径'
        print('获取半径')
        return self._r
    #setter前面的r必须与@property 修饰的方法名r一致
    #@r.setter装饰的方法名r必须与@property 修饰的方法名r一致
    @r.setter 
    def r(self,value):
        print('设置半径')
        if value<0:
            raise ValueError('半径不能小于0')
        self._r=value
    #deleter前面的r必须与@property 修饰的方法名r一致
    #@r.deleter装饰的方法名r必须与@property 修饰的方法名r一致
    @r.deleter 
    def r(self):
        print('删除半径')
        del self._r
    @property
    def c(self):
        print('获取周长')
        self._c=2*self.pi*self._r
        return self._c
    @property
    def s(self):
        print('获取面积')
        self._s=self.pi*(self._r**2)
        return self._s
    # @c.setter装饰的方法名sc与@property 修饰的方法名c不一致,报错
    @c.setter
    def sc(self,value):
        print('设置周长')
        self._c=value
    # @c.deleter装饰的方法名dc与@property 修饰的方法名c不一致,报错
    @c.deleter
    def dc(self,value):
        print('删除周长')
        del self._c
    #@property创建的属性,必须返回一个值,否则无法访问该属性
    @property
    def d(self):
        'doc:定义直径'
        print('获取直径')
        self._d=2*self._r

        
>>> c1=PTCircle(2)
>>> c1.r
获取半径
2
>>> del c1.r
删除半径
>>> c1.r=3
设置半径
>>> c1.r
获取半径
3
>>> c1.c
获取周长
18.84
>>> c1.s
获取面积
28.26
>>> PTCircle.r.__doc__
'doc:定义半径'
>>> c1.c=1
Traceback (most recent call last):
  File "<pyshell#171>", line 1, in <module>
    c1.c=1
AttributeError: can't set attribute
>>> del c1.c
Traceback (most recent call last):
  File "<pyshell#172>", line 1, in <module>
    del c1.c
AttributeError: can't delete attribute
#@property创建的属性,必须返回一个值,否则无法访问该属性
#没有返回直径的值
>>> c1.d
获取直径
文章来源:https://blog.csdn.net/sinat_34735632/article/details/135371408
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。