Python面向对象编程第18篇 属性装饰器
Posted 不剪发的Tony老师
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python面向对象编程第18篇 属性装饰器相关的知识,希望对你有一定的参考价值。
本篇我们学习 Python 属性装饰器(@property)的原理。
属性装饰器
在上一篇中,我们介绍了如何利用 property 类定义类的属性。property 类的调用语法如下:
property(fget=None, fset=None, fdel=None, doc=None)
以下代码定义了一个 Person 类包含两个属性 name 和 age:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
使用 property 类定义 age 属性的 getter 方法:
class Person:
def __init__(self, name, age):
self.name = name
self._age = age
def get_age(self):
return self._age
age = property(fget=get_age)
property() 方法接受一个 getter 方法作为参数,返回一个 property 对象。
以下示例创建了一个 Person 类实例,通过实例获取 age 属性的值:
john = Person('John', 25)
print(john.age)
输出结果如下:
25
另外,我们也可以直接调用 Person 对象的 get_age() 方法:
print(john.get_age())
也就是说,我们既可以利用 age 属性获取年龄,也可以通过 get_age() 方法获取年龄。这两种方式是不必要的重复,为了减少重复,我们可以将 get_age() 方法重命名为 age():
class Person:
def __init__(self, name, age):
self.name = name
self._age = age
def age(self):
return self._age
age = property(fget=age)
property() 方法接受一个可调用对象(age),同时返回一个可调用对象。因此它是一个装饰器。我们可以使用 @property 装饰器装饰 age() 方法:
class Person:
def __init__(self, name, age):
self.name = name
self._age = age
@property
def age(self):
return self._age
通过使用 @property 装饰器,我们可以简化类的属性定义。
Setter 装饰器
以下代码为 Person 类增加了一个 setter 方法(set_age),用于为 _age 属性赋值:
class Person:
def __init__(self, name, age):
self.name = name
self._age = age
@property
def age(self):
return self._age
def set_age(self, value):
if value <= 0:
raise ValueError('The age must be positive')
self._age = value
为了将 set_age 赋予 age 属性对象的 fset 参数,可以调用 age 属性对象的 setter() 方法:
class Person:
def __init__(self, name, age):
self.name = name
self._age = age
@property
def age(self):
return self._age
def set_age(self, value):
if value <= 0:
raise ValueError('The age must be positive')
self._age = value
age = age.setter(set_age)
setter() 方法接受一个可调用对象参数,同时返回另一个可调用对象(属性对象)。所以,我们可以使用 @age.setter 属性装饰器装饰 set_age() 方法:
class Person:
def __init__(self, name, age):
self.name = name
self._age = age
@property
def age(self):
return self._age
@age.setter
def set_age(self, value):
if value <= 0:
raise ValueError('The age must be positive')
self._age = value
现在我们可以将 set_age() 方法重命名为 age() 方法,并且在 __init__() 方法中使用 age 属性:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if value <= 0:
raise ValueError('The age must be positive')
self._age = value
总结来说,我们可以使用装饰器创建属性:
class MyClass:
def __init__(self, attr):
self.prop = attr
@property
def prop(self):
return self._attr
@prop.setter
def prop(self, value):
self._attr = value
在以上方式中,__attr 是私有属性,prop 是属性名。
以下示例使用 @property 装饰器为 Person 类创建了两个属性 name 和 age:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if value <= 0:
raise ValueError('The age must be positive')
self._age = value
@property
def name(self):
return self._age
@name.setter
def name(self, value):
if value.strip() == '':
raise ValueError('The name cannot be empty')
self._age = value
总结
- 属性装饰器(@property)可以创建类的属性。
以上是关于Python面向对象编程第18篇 属性装饰器的主要内容,如果未能解决你的问题,请参考以下文章
Python入门-6面向对象编程:06私有属性和私有方法(实现封装)-@property装饰器-get和set方法-总结