我们知道Python中私有属性是前面加两道下划线,然后在访问时就会报“object has no attribute 。。。”。事实上Python的这种私有属性只是一种规范,其实通过“_类名__属性名”还是可以读写的,如下。
class Dog():
def __init__(self, age: int):
self.__age = age
dog = Dog(8)
print(dog.__age)#AttributeError: 'Dog' object has no attribute '__age'
print(dog._Dog__age) #8
#写也是类似的
所以Python似乎并没有真正的私有属性,但不妨忘记这种流氓访问方式。
再说@property,假如我们需要定义一个只读属性。写个getter方法可以实现,但如果想用访问属性的方式去读呢?这就可以用@property,如下。
class Dog():
def __init__(self, age: int):
self.__age = age
@property
def age(self) -> int: return self.__age
dog = Dog(8)
print(dog.age)#可读不可写
换句话说@property的作用就是把方法变成了一个属性。从property源码可以看到该类包含getter、setter、deleter三个方法。
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
@property所装饰的方法实现的是getter,另外我们可以在@property后面通过@xxx.setter、@xxx.deleter实现setter、deleter。比如,@age.setter可以以直接访问属性的方式修改属性,同时可以在修改时加入一些逻辑。
@age.setter
def age(self, age):
if age < 0:
raise Exception("age must be positive")
self.__age = age
至于Python中的@property、@xxx.setter相比java常用的getter、setter有什么优点,我想就是@property、@xxx.setter形式上不需要调用方法,直接通过属性来访问吧。



