200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 【Python面向对象编程】第18篇 属性装饰器

【Python面向对象编程】第18篇 属性装饰器

时间:2022-03-11 16:49:39

相关推荐

【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 = nameself.age = age

使用 property 类定义 age 属性的 getter 方法:

class Person:def __init__(self, name, age):self.name = nameself._age = agedef get_age(self):return self._ageage = 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 = nameself._age = agedef age(self):return self._ageage = property(fget=age)

property() 方法接受一个可调用对象(age),同时返回一个可调用对象。因此它是一个装饰器。我们可以使用 @property 装饰器装饰 age() 方法:

class Person:def __init__(self, name, age):self.name = nameself._age = age@propertydef age(self):return self._age

通过使用 @property 装饰器,我们可以简化类的属性定义。

Setter 装饰器

以下代码为 Person 类增加了一个 setter 方法(set_age),用于为 _age 属性赋值:

class Person:def __init__(self, name, age):self.name = nameself._age = age@propertydef age(self):return self._agedef 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 = nameself._age = age@propertydef age(self):return self._agedef set_age(self, value):if value <= 0:raise ValueError('The age must be positive')self._age = valueage = age.setter(set_age)

setter() 方法接受一个可调用对象参数,同时返回另一个可调用对象(属性对象)。所以,我们可以使用 @age.setter 属性装饰器装饰 set_age() 方法:

class Person:def __init__(self, name, age):self.name = nameself._age = age@propertydef age(self):return self._age@age.setterdef 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 = nameself.age = age@propertydef age(self):return self._age@age.setterdef 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@propertydef prop(self):return self._attr@prop.setterdef prop(self, value):self._attr = value

在以上方式中,__attr 是私有属性,prop 是属性名。

以下示例使用 @property 装饰器为 Person 类创建了两个属性 name 和 age:

class Person:def __init__(self, name, age):self.name = nameself.age = age@propertydef age(self):return self._age@age.setterdef age(self, value):if value <= 0:raise ValueError('The age must be positive')self._age = value@propertydef name(self):return self._age@name.setterdef name(self, value):if value.strip() == '':raise ValueError('The name cannot be empty')self._age = value

总结

属性装饰器(@property)可以创建类的属性。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。