> 文档中心 > Python中通过property实现属性的修改、删除、查看

Python中通过property实现属性的修改、删除、查看


1. property的作用

在Python中,属性可以完成赋值、取值、删除的操作。如果我们想要在完成这些操作前,进行属性的校验工作(例如:赋值前判断数据的有效性、删除前判断合法性身份),则需要在方法中完成。

那么有没有既能检查参数,又可以用类似属性这样简单的方式来访问类的变量呢?

有的,我们可以通过property,来实现既能检查属性,还能用属性的方式来访问该属性的功能

2. property的本质——property类

property()的实例化方式:property(fget=None, fset=None, fdel=None, doc=None)

参数说明:

  • fget : 用于获取属性值的函数

  • fset : 用于设置属性值的函数

  • fdel : 用于删除属性值的函数

  • doc : 文档字符串

根据上述说明,如果要对property类进行实例化,需要传入相关功能的函数。

class Person:    def __init__(self): self.__age = 0    def get_age(self): return self.__age    def set_age(self, num): if num >= 18:     self.__age = num else:     raise ValueError('Age below 18 is not possible.')    def del_age(self): print('将要删除age属性') del self.__age    # 对象age则是我们调用的属性,通过age可以完成获取、赋值、删除的操作    age = property(get_age, set_age, del_age)person = Person()# 获取属性值print(person.age)# 设置属性值person.age = 19print(person.age)# 删除属性值del person.age

3. 使用装饰器定义只读属性

@property 语法糖提供了比 property() 函数更简洁直观的写法。

Python内置的@property装饰器可将一个方法变成属性调用。

并且得到是只读属性,也是得到是真正意义上的私有属性。我们无法通过赋值的方式,修改属性值。

(1)未使用property装饰的情况

# 未使用property装饰的情况class Person: def __init__(self): self.__age = 0 def age(self): return self.__age# 调用方式person = Person()age = person.age()print(age)# 输出结果"""0"""

(2)使用property装饰后的情况

# 使用property装饰后的情况class Person:    def __init__(self): self.__age = 0 @property    def age(self): return self.__age      # 调用方式person = Person()age = person.ageprint(age)# 输出结果"""0"""

4. 使用装饰器设置属性的方式

由于通过 @property 将方法变为只读属性。此时如果添加修改属性的方式,可以通过 @属性名.setter 方式来完成。

例如,在上述代码中,通过 @property 添加了一个 age属性,接下来我们就可以使用 @age.setter 装饰同名的 age()方法 ,添加赋值的功能。需要注意的是当前age() 方法的第二个参数用来接收值。操作方式如下:

Person 类中,创建同名的 age()方法,第二个参数num用来获取赋值参数,然后给该方法添加 @age.setter 装饰器,使得 age 属性拥有赋值操作。

class Person:    def __init__(self): self.__age = 0    @property    def age(self): return self.__age    @age.setter    def age(self, num): if num >= 18:     self.__age = num else:     raise ValueError('Age below 18 is not possible.')     # 调用person = Person()print(person.age)person.age = 19print(person.age)person.age = 4print(person.age)# 输出结果"""019Traceback (most recent call last):  File "/Users/bingyao/Desktop/面试题/code/tuple与list的区别.py", line 70, in     person.age = 4  File "/Users/bingyao/Desktop/面试题/code/tuple与list的区别.py", line 60, in age    raise ValueError('Age below 18 is not possible.')ValueError: Age below 18 is not possible."""

从打印结果来看,在给 age 赋值的时候,程序是执行了 raise ValueError('Age below 18 is not possible.') 。因此,想要通过方法完成类似于属性赋值的方式,通过 @属性.setter 是可以实现的。

5. 使用装饰器设置属性的删除操作

通过装饰器给属性设置删除操作的方式同赋值方式大致相同,唯一的却别就在于使用的是装饰器为 @属性名.deleter 通过此装饰器可以将方法变为方法名字的属性,来完成删除操作。

class Person:    def __init__(self): self.__age = 0    @property    def age(self): return self.__age    @age.setter    def age(self, num): if num >= 18:     self.__age = num else:     raise ValueError('Age below 18 is not possible.')    @age.deleter    def age(self):  # 由于这里的方法名为age,所以要删除属性,需要使用age print('将要删除age属性') del self.__ageperson = Person()print(person.age)person.age = 19print(person.age)del person.age

小结

(1) property本质是一个类,通过给 property 提供不同的功能的函数,完成属性的改、查、删的操作。实例对象名字即为调用属性的名字。

(2) @property广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性。

(3) @property 语法糖提供了比 property() 函数更简洁直观的写法。

  • a. 被 @property 装饰的方法是获取属性值的方法,被装饰方法的名字会被用做 属性名
  • b. 被 @属性名.setter 装饰的方法是设置属性值的方法
  • c. 被 @属性名.deleter 装饰的方法是删除属性值的方法

转载自个人博客-原文地址

在这里插入图片描述

学IT,上博学谷