[转载]Python中@property和@setter的用法

原文地址:https://www.cnblogs.com/yeer-xuan/p/13488291.html

问题引出

  在业务处理时经常需要在数据的读取和存入前对数据进行预处理,通过@property和@*.setter两个装饰器就可以方便的实现。

 

@property

python中的@property装饰器可以总结为两个作用:

  1. 让函数可以像普通变量一样使用
  2. 对要读取的数据进行预处理

 

示例1

我们先编写一个测试类:

假设现在我们需要将name与age合并成一个新属性tag,在不使用@property和修改类属性的情况下我们可能会这样写:

复制代码

复制代码

这种方式自然没有问题,但是tag与其说是一个函数其实更像是user对象的一个属性,用user.tag()的方法获取显得不那么自然,而使用@property装饰器我们就可以用user属性的方式来得到tag:

复制代码

复制代码

对于tag来说使用类属性 user.tag 的方式获取会比 user.tag() 更加的合理。

 

示例2

我们使用和上文一样的测试类,现在我们需要在读取user的age属性时必须在原来的基础上+5(预处理),但是不能修改类中保存的age值,在不使用@property的情况下我们可能会这样写:

复制代码

复制代码

和示例1的问题相同,我们需要用函数调用的方式来获取预处理后的age值,而使用@property我们就可以更方便的进行预处理操作:

复制代码

复制代码

我们先修改类属性age为_age,然后为age方法加上@property装饰器,这样我们在外面就可以用user.age方便的获取预处理后的值了。

 

通过@property我们实现了在读取类属性前对数据进行预处理,那么我们能不能在数据从外部存入类属性前对数据进行预处理呢?

 

@*.setter

python中的@*.setter装饰器可以总结为两个作用:

  1. 对要存入的数据进行预处理
  2. 设置可读属性(不可修改)

注意:@*.setter装饰器必须在@property装饰器的后面,且两个被修饰的函数的名称必须保持一致,* 即为函数名称。

 

示例1

我们使用和上文一样的测试类,现在我们需要在数据存入user.age前先对其+5,利用@*.setter装饰器我们可以这样写:

复制代码

复制代码

当执行 user.age = 5 时,@age.setter装饰器下的age函数会将数据+5后再存入类属性_age中,实现了存入前对数据的预处理。

 

示例2

通过@*.setter装饰器,我们可以方便的设置只读属性,即无法对属性进行修改:

复制代码

复制代码

在为age赋值时会立即触发@age.setter装饰器下的age函数中的提示语句或者异常处理语句。

 

综合示例

通过@*.setter和@property的组合使用我们就可以实现密码的密文存储和明文输出,具体步骤为:用户输入明文->转化为密文后存入->用户读取时先转化为明文再输出。

复制代码

复制代码

 

总结:为两个同名函数打上@*.setter装饰器和@property装饰器后,当把函数作为变量赋值时会触发@*.setter对应的函数,当把函数作为变量读取时会触发@property对应的函数,因此我们可以将其用于数据的预处理。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据