python中的property装饰器

既要保护类的封装特性,又要让开发者可以使用“对象.属性”的方式操作操作类属性,除了使用 property() 函数,Python 还提供了 @property 装饰器。通过 @property 装饰器,可以直接通过方法名来访问方法,不需要在方法名后添加一对“()”小括号。

@property 的语法格式如下:

@property
def 方法名(self)
    代码块

例如,定义一个矩形类,并定义用 @property 修饰的方法操作类中的 area 私有属性,代码如下:

class Rect:
    def __init__(self,area):
        self.__area = area
    @property
    def area(self):
        return self.__area
rect = Rect(30)
#直接通过方法名来访问 area 方法
print("矩形的面积是:",rect.area)

 

运行结果为:

矩形的面积为: 30

上面程序中,使用 @property 修饰了 area() 方法,这样就使得该方法变成了 area 属性的 getter 方法。需要注意的是,如果类中只包含该方法,那么 area 属性将是一个只读属性。


也就是说,在使用 Rect 类时,无法对 area 属性重新赋值,即运行如下代码会报错:

rect.area = 90
print("修改后的面积:",rect.area)

运行结果为:

Traceback (most recent call last):
  File "C:\Users\mengma\Desktop\1.py", line 10, in <module>
    rect.area = 90
AttributeError: can't set attribute

而要想实现修改 area 属性的值,还需要为 area 属性添加 setter 方法,就需要用到 setter 装饰器,它的语法格式如下:

@方法名.setter
def 方法名(self, value):
    代码块

 

例如,为 Rect 类中的 area 方法添加 setter 方法,代码如下:

@area.setter
def area(self, value):
    self.__area = value

再次运行如下代码:

rect.area = 90
print("修改后的面积:",rect.area)

运行结果为:

修改后的面积: 90

这样,area 属性就有了 getter 和 setter 方法,该属性就变成了具有读写功能的属性。


除此之外,还可以使用 deleter 装饰器来删除指定属性,其语法格式为:

@方法名.deleter
def 方法名(self):
    代码块

例如,在 Rect 类中,给 area() 方法添加 deleter 方法,实现代码如下:

@area.deleter
def area(self):
    self.__area = 0

然后运行如下代码:

del rect.area
    print("删除后的area值为:",rect.area)

运行结果为:

删除后的area值为: 0

 案例:不使用property装饰器实现分页

 1 #利用property装饰器实现分页
 2 
 3 li=[x for x in range(100)]
 4 class PageBean:
 5     def __init__(self,value):
 6         if value.isdigit():
 7             self.page=int(value)
 8         else:
 9             self.page=1       
10     def start(self):
11         return (self.page-1)*10
12     def end(self):
13         return self.page*10
14 while True:
15    p=input("请输入你要查看的页码(退出请按0):")
16    if not(p.isdigit()):
17        print("输入错误,请重新输入")
18    else:
19        if int(p)==0:
20            break
21        else:
22            pageBean=PageBean(p)
23            liP=li[pageBean.start():pageBean.end()]
24            print(liP)
不使用property装饰器

使用property装饰器

 1 #利用property装饰器实现分页
 2 
 3 li=[x for x in range(100)]
 4 class PageBean:
 5     def __init__(self,value):
 6         if value.isdigit():
 7             self.page=int(value)
 8         else:
 9             self.page=1
10     #使用property装饰器进行装饰
11     @property 
12     def start(self):
13         return (self.page-1)*10
14     @property
15     def end(self):
16         return self.page*10
17 while True:
18    p=input("请输入你要查看的页码(退出请按0):")
19    if not(p.isdigit()):
20        print("输入错误,请重新输入")
21    else:
22        if int(p)==0:
23            break
24        else:
25            pageBean=PageBean(p)
26            liP=li[pageBean.start:pageBean.end]#此处调用不用括号,形式上和属性一直
27            print(liP)
使用property装饰器

 

posted @ 2020-02-12 18:21  风雪泪  阅读(1928)  评论(0编辑  收藏  举报