理解
如果不把属性私有,相当于代码裸奔,缺少逻辑验证,因此要封装一下,通过双下划线私有化,这样如果需要变更属性的范围之类的只需要操作set_name(self,value)这个方法
- @property 和@name.setter两个方法,是为了拦截对属性的操作。@property拦截读操作,@name.setter拦截写操作
- 如果只有@property 是只读操作
如下代码为封装的理解
class Wife:
def __init__(self,name,age):
self.set_name(name)
self.set_age(age)
def get_name(self):
return self.__name
def set_name(self,value):
self.__name = value
def get_age(self):
return self.__age
def set_age(self, value):
if 20 <= value <= 30:
self.__age = value
else:
print("不需要")
w1 = Wife("芳芳",23)
高效版,终极版,注释为关键知识点
class Wife:
def __init__(self,name,age):
self.name = name
self.age = age
# 拦截读取变量的操作
# 本质:创建property对象,name存储对象地址
# 注意:创建对象时,会指定读取方法
# name = property(get_name,set_name)
@property
def name(self): #get_name()
return self.__name
#拦截写入变量的操作,方便操作,可以进行逻辑判断
@name.setter #set_name()
def name(self,value):
self.__name = value
@property
def age(self):
return self.__age
@age.setter
def age(self, value):
if 20 <= value <= 30:
self.__age = value
else:
self.__age = 0
print("不需要")
w1 = Wife("芳芳",86)
print(w1.name)
print(w1.age)
#运行结果
不需要
芳芳
0
只读,读写结合,以及注意可变类型和不可变类型
class Person:
def __init__(self,name):
#人的姓名
self.name = name
#人会的技能
self.__skills = []
self.__totle_money = 0
#只读属性
@property
def skills(self):
#return self.__skills 返回可变对象地址,意味着类外扔可以操作可变对象
return self.__skills[:] #返回新的可变对象地址,意味着类外仍然操作的是新可变对象,不影响原对象
# 备注:每次通过切片返回新对象,都会另外开辟空间创建新对象,专用过多内存
#只读属性
@property
def totole_mone(self):
return self.__totle_money
@property
def name(self):
return self.__name
@name.setter
def name(self,value):
self.__name = value
def teach(self,person_other,str_skill):
#person_other 的技能表,增加srt_skill,person_other参数传入的是类
person_other.__skills.append(str_skill)
print(self.name,"教了",person_other.name,str_skill)
def work(self,money):
self.__totle_money += money
print(self.name,"工作挣了",money,"元")
zs = Person("张三")
ls = Person("李四")
#张三叫李四学python
zs.teach(ls,"python")
zs.work(8000)
# zs.skills = [] #不能改
#如果skills属性,返回的是__skills,那么仍然可以操作私有列表
#__skills[:],那么操作的是新列表
zs.skills.append("python")
print(zs.skills)
#结果
张三 教了 李四 python
张三 工作挣了 8000 元
[]