Python中@property和@setter的用法

您所在的位置:网站首页 javagetter和setter添加判断语句 Python中@property和@setter的用法

Python中@property和@setter的用法

2024-07-03 19:04| 来源: 网络整理| 查看: 265

问题引出

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

 

@property

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

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

 

示例1

  我们先编写一个测试类:

class User(): def __init__(self, name, age): self.name = name self.age = age

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

class User(): def __init__(self, name, age): self.name = name self.age = age def tag(self): return self.name + str(self.age) user = User('xiao',5) print(user.tag())

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

class User(): def __init__(self, name, age): self.name = name self.age = age @property def tag(self): return self.name + str(self.age) user = User('xiao',5) print(user.tag)

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

 

示例2

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

class User(): def __init__(self, name, age): self.name = name self._age = age def age(self): return self.age + 5 user = User('xiao',5) print(user.age())

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

class User(): def __init__(self, name, age): self.name = name self._age = age @property def age(self): return self._age + 5 user = User('xiao',5) print(user.age)

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

 

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

 

@*.setter

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

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

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

 

示例1

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

class User(): def __init__(self, name, age): self.name = name self._age = age @property def age(self): return self._age @age.setter def age(self,n): self._age = n + 5 user = User('xiao',0) user.age = 5 print(user.age)# 结果:10

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

 

示例2

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

class User(): def __init__(self, name, age): self.name = name self._age = age @property def age(self): return self._age @age.setter def age(self,n): print('数据不能被修改') user = User('xiao',0) user.age = 5

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

 

综合示例

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

class User(): def __init__(self, name): self.name = name self._password = '' # 密文存储 @property def password(self): return decryption(self._password) # 解密 @password.setter def password(self,word): self._password = encryption(word) # 加密 user = User('xiao') user.password = '123' #明文输入 print(user.password) #明文输出

 

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

  



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3