目录
直接访问
Getters和Setters
property()
@property
私有属性__name
类属性和对象属性
在Python中,对象属性和方法通常是public的。
直接访问
class Duck:
def __init__(self, input_name):
self.name = input_name
if __name__ == "__main__":
fowl = Duck('Daffy')
print(fowl.name)
fowl.name = 'Daphne'
print(fowl.name)
# ======输出======= #
Daffy
Daphne
如果希望对属性设置一些私密性,可以使用下面方法:
Getters和Setters
对于面向对象中一些私有对象属性,是不能由类外访问的,程序员需要写一些读取属性或设定属性的函数。
Python并没有私有属性,但是可以写getters和setters来实现私有。
class Duck: def __init__(self, input_name): self.hidden_name = input_name def get_name(self): print("Inside the getter.") return self.hidden_name def set_name(self, input_name): print("Inside the setter.") self.hidden_name = input_name if __name__ == "__main__": fowl = Duck('Daffy') print(fowl.get_name()) fowl.set_name("Daphne") print(fowl.get_name()) # ======输出======= # Inside the getter. Daffy Inside the setter. Inside the getter. Daphne
property()
class Duck:
def __init__(self, input_name):
self.hidden_name = input_name
def get_name(self):
print("Inside the getter.")
return self.hidden_name
def set_name(self, input_name):
print("Inside the setter.")
self.hidden_name = input_name
name = property(get_name, set_name)
if __name__ == "__main__":
fowl = Duck('Daffy')
print(fowl.get_name())
fowl.set_name("Daphne")
print(fowl.get_name(), 'n')
don = Duck('Donald')
print(don.name)
don.name = 'Donna'
print(don.name)
# ======输出======= #
Inside the getter.
Daffy
Inside the setter.
Inside the getter.
Daphne
Inside the getter.
Donald
Inside the setter.
Inside the getter.
Donna
@property
class Duck:
def __init__(self, input_name):
self.hidden_name = input_name
@property
def name(self):
print("Inside the getter.")
return self.hidden_name
@name.setter
def name(self, input_name):
print("Inside the setter.")
self.hidden_name = input_name
if __name__ == "__main__":
fowl = Duck('Daffy')
print(fowl.name)
fowl.name = "Daphne"
print(fowl.name)
# ======输出======= #
Inside the getter.
Daffy
Inside the setter.
Inside the getter.
Daphne
class Duck: def __init__(self, input_name): self.hidden_name = input_name @property def name(self): print("Inside the getter.") return self.hidden_name @name.setter def name(self, input_name): print("Inside the setter.") self.hidden_name = input_name if __name__ == "__main__": fowl = Duck('Daffy') print(fowl.name) fowl.name = "Daphne" print(fowl.name) # ======输出======= # Inside the getter. Daffy Inside the setter. Inside the getter. Daphne
也可以用于计算数值,可以像类有radius属性一样以属性方式调用diameter函数。且当我们改变radius属性后,diameter也会跟着改变。如果没有指定属性的setter property,就不能在外部设定值。
class Circle(): def __init__(self, radius): self.radius = radius @property def diameter(self): return 2 * self.radius if __name__ == "__main__": c = Circle(5) print(c.radius) print(c.diameter) c.radius = 7 print(c.radius) print(c.diameter) c.diameter = 20 # =====输出===== # 5 10 7 14 Error: .... can't set attribute
对直接属性访问,使用property的另一个好处是,如果改变了属性的定义,只需要更改类定义中的代码,不用修改所有函数中的属性。
私有属性__name
Python对于类定义外不可见的属性命名有一个传统,即__name(双下划线在前)。
class Duck(): def __init__(self, input_name): self.__name = input_name @property def name(self): print("Inside the getter.") return self.__name @name.setter def name(self, input_name): print("Inside the setter.") self.__name = input_name if __name__ == '__main__': fowl = Duck('Howard') print(fowl.name) fowl.name = 'Donald' print(fowl.name) print(fowl._Duck__name) # 还是能打印出来的 print(fowl.__name) # =====输出===== # Inside the getter. Howard Inside the setter. Inside the getter. Donald Donald Error: ...
尽管这个命名传统并不是使属性完全private,但Python让属性名不太可能被外部代码改变。
类属性和对象属性
可以给类属性赋值,这个值会被对象继承。
如果改变对象的属性值,不会影响类的属性值。
如果后续改变了类的属性值,不会影响已经存在的对象的属性值,但是会影响新建的对象属性值。