对实例属性的获取和访问,我们希望增加一些额外的处理过程,比如说检查类型或者验证。
要定义对属性的访问,一种简单的方式是将其定义为property。
传统方法
class Person(object):
def __init__(self, age):
self.__age = age
def get_age(self):
return self.__age
def set_age(self, age):
if not isinstance(age, int) or age < 0:
raise ValueError("age ust be int")
self.__age = age
c = Person(100)
print(c.age) # 报错 不能这样访问
print(c.get_age()) # 100,访问方式比较繁琐
方法一(已经存在get和set方法的 + )
class Person1(object):
def __init__(self, age):
self.__age = age
def get_age(self):
return self.__age
def set_age(self, age):
if not isinstance(age, int) or age < 0:
raise ValueError("age ust be int")
self.__age = age
# 增加这一句
age = property(get_age, set_age)
a = Person1(100)
print(a.age) # 100 可以直接访问,不用调用方法
print(a.get_age()) # 100 这样调用方法也可以访问
a.age = 9
print(a.age) # 9
方法二
class Person2(object):
def __init__(self, age):
self.__age = age
@property # 增加property装饰器
def age(self):
return self.__age
@age.setter # 增加age.setter装饰器
def age(self, age):
if not isinstance(age, int) or age < 0:
raise ValueError("age ust be int")
self.__age = age
# 注意使用这种方法的时候,都是使用age方法
a = Person2(100)
print(a.age) # 100
a.age = 88
print(a.age) # 88
a.age = -8
print(a.age) # 报错
property也可以用来定义需要计算的属性,这类属性并不会实际保存起来,二时根据需要完成计算
import math
class Circle:
def __init__(self, radius):
self.radius = radius
@property
def area(self):
return math.pi * self.radius ** 2
@property
def perimeter(self):
return 2 * math.pi * self.radius
c1 = Circle(5)
print(c1.radius)
print(c1.area)
print(c1.perimeter)