目录
- 一、前言
- 二、定义
一、前言
在 Python 类这一节中,会涉及到属性的私有化,私有化的好处在于我们无法轻易地更改类体中属性值,而对于类体中的私有化属性其实也并非真正的私有化,而是一种伪私有化,我们可通过 dir() 内置函数来验证。如果你想要更新私有化属性,我们一般常用的方法无非就是在类体中定义 setxxx()、getxxx() 方法来实现。除了这种方式外,我们还可以通过装饰器 property 来实现同样的效果。
二、定义
没有 property 装饰器前,我们一般通过 set() 方法修改属性值:
class Student:
def __init__(self, name, age):
self.name = name
self.__age = age
def setAge(self, age):
if age > 0 and age < 120:
self.__age = age
else:
print('年龄输入错误!')
def getAge(self):
return self.__age
def __str__(self):
return '姓名:{},年龄:{}'.format(self.name, self.__age)
s = Student('zhurs', 100)
# 不修改属性
print(s)
# name没有私有化,因此类体外可直接修改
s.name = 'rab'
print(s)
# age私有化了,但类体中设置了set方法,因此可以通过set方法来修改age
s.setAge(50)
print(s)
定义 property 后(和之前我们定义的方式一样,在某原函数前 @property)
class Student:
def __init__(self, name, age):
self.name = name
self.__age = age
@property
def age(self):
return self.__age
def __str__(self):
return '姓名:{},年龄:{}'.format(self.name, self.__age)
s = Student('zhurs', 100)
# 不修改属性
print(s)
# name没有私有化,因此类体外可直接修改
s.name = 'rab'
print(s)
# 加装饰器后,此时age可直接获取,也就是说此时的装饰器相当于前面的get()方法
print(s.age)
此时你会发现,我们在类体外获取类中 __age
属性值的时候,并不需要 s.__age
,而是 s.age
,我们可以利用 dir() 内置函数来查看 s 这个对象的属性列表:
...
# name没有私有化,因此类体外可直接修改
s.name = 'rab'
print(s)
# 加装饰器后,此时age可直接获取,也就是说此时的装饰器相当于前面的get()方法
print(s.age)
# 打印s对象中的属性列表
print(s.__dir__())
可见,s 对象中有 age 这个属性,因此可以类体外直接获取,当然,由于 __age 本身就是一个私有化属性,其底层也是做了伪私有化_Student__age
。
那这个时候能直接 s.__age = xxx
对该私有化属性进行更新吗?答案是不能的(从这个装饰器的底层可知道),此时还需要对装饰器下面的函数进一步设置 setter,才能在类体外进行 s.__age = xxx
操作,如下:
class Student:
def __init__(self, name, age):
self.name = name
self.__age = age
# 1.类似没有装饰器之前的自定义get函数
@property
def age(self):
return self.__age
# 2.类似没有装饰器之前的自定义set函数
@age.setter
def age(self, age):
if age > 0 and age < 120:
self.__age = age
else:
print('年龄输入错误!')
def __str__(self):
return '姓名:{},年龄:{}'.format(self.name, self.__age)
s = Student('zhurs', 100)
# 不修改属性
print(s)
# name没有私有化,因此类体外可直接修改
s.name = 'rab'
print(s)
# 加装饰器后,此时age可直接获取,也就是说此时的装饰器相当于前面的get()方法
print(s.age)
# 修改私有化属性age值
s.age = 50
print(s)
因此,property 装饰器的作用就是能够将私有化的属性转为像未私有化的属性使用(即类体外直接获取值或更新值)。
—END