面向对象
只读属性的概念和含义
概念:一个属性(一般指实例属性),只能读取,不能写入
应用场景:有些属性,只限在内部根据不同场景进行修改,而对外界来说,不能修改,只能读取。比如:电脑类的网速属性,网络状态属性
只读属性的实现
方案1:
方案:
全部隐藏:私有化,既不能读,也不能写
部分公开:公开读的操作
具体实行:
私有化:通过"属性前置双下划线实现"
部分公开:通过公开的方法
#全部隐藏,部分公开
class Person: #私有化操作
def __init__(self):
self.__age = 18
def getAge(self): #公开
return self.__age
p1 = Person()
print(p1.getAge())
#18
优化:使用property装饰器
作用:将一些‘属性的操作方法’关联到一个属性中
class Person: #私有化操作
def __init__(self):
self.__age = 18
@property #主要作用就是,可以以使用属性的方式,来调用这个方法
def age(self): #公开
return self.__age
p1 = Person()
print(p1.age)
#p1.age = 666 #不能修改会报错
#18
property在新式类和经典类中的区别
新式类 继承(object) :object就是一个类
经典类:没有继承(object)
python2.x版本定义一个类时,默认不继承(boject)
python3.x版本定义一个类时,默认继承(object)
建议使用新式类
#Python3.x中
class Person:
pass
print(Person.__bases__) #结果出现object表示时新式类,反之经典类
#Python2.x如果定义一个类,没有显示继承自object,那么这个类就是一个经典类
#必须显示继承自object,它才是一个新式类
#Python3.x,如果直接定义一个类,会隐式的继承object,默认情况下,就已经是一个新式类
#Python2.x中
class Person(object): #手动添加object,3.x也可以
pass
print(Person.__bases__) #查看是经典类还是新式类
property在新式类以及在经典类中的使用方式
新式类:
#第一种使用方式
class Person(object):
def __init__(self):
self.__age = 18 #添加私有化属性
def get_age(self): #用来操作age的写入方法
return self.__age
def set_age(self, value): #age的获取方法
self.__age = value
age = property(get_age, set_age)
p = Person()
print(p.age)
p.age = 90
print(p.age)
#第二种使用方式
class Person(object): #只管理get方法
def __init__(self):
self.__age = 18
@property
def age(self):
return self.__age
@age.setter
def age(self, value):
self.__age = value
p = Person
print(p.age)
p.age = 10
print(p.age)
经典类:
#先要版本切换到2.x
class Person:
def __init__(self):
self.__age = 18
def get_age(self):
return self.__age
def set_age(self, value):
self.__age = value
age = property(get_age, set_age)
p = Person()
print p.age
p.age = 19 #此处是新增了一个属性,并不是惊醒修改
print(p.age)
#装饰器方式
class Person:
def __init__(self):
self.__age = 18
@propetty
def age(self):
return self.__age
@age.setter
def age(self. value)
self .__age = vlaue
p = Person()
print p.age
p.age = 19
print p.age
print p.__dict__
#19
#{'age': 19, '_Person__age': 18}
#只能关联相关的读取方法,不能关联其他方法
方案2:
class Person:
#当我们通过 "实例.属性 = 某一个值",给一个实例增加一个属性,
#或者说,修改一下属性值的时候,都会调用这个方法
#在这个方法的内部,才会真正的把这个属性,以及对应的数据,
#给存储到__dict__字典里面
def __setter__(self, key, value):
print(key, value)
#1.判定key,是否是我们要设置的质地属性的名称
if key == "age" and key in self.__dict__.keys():
#keys表示获取keys列表,然后判断key是否在keys列表中
#self.__dict__ 获取属性:值
print("这个属性是只读属性,不能进行设置")
#2.如果不是,只读属性的名称,真正的给它添加到这个实例里面去
else:
self.key = value
self.__dict__[key] = value
p1 = Person()
p1.age = 18
print(p1.age)
p1.age = 999
print(p1.__dict__)
#age 18
#18
#age 999
#这个属性是只读属性,不能进行操作
#18
#{'age': 18}