目录
类的封装
将类的属性或方法隐藏,这些属性和方法只能在内部使用,外部无法使用。类的封装在类定义阶段就执行了,会把私有属性_x
变成_类名__x
两个层面的封装
第一个层面
第一个层面的封装(什么都不用做):创建类和对象会分别创建二者的名称空间,我们只能用类名.或者obj.的方法去访问里面的名字,这本身就是一种封装
第二个层面
第二个层面的封装:类中把某些属性和方法隐藏起来(或者说定义成私有的)只在类的内部使用、外部无法访问,或者留下少量接口(函数)功外部访问
在python中用双下划线的方式实现隐藏属性(设成私有的)
class People: __name = 'nick' # 设置成私有属性,在内部可以使用,在外部无法使用 print(__name) # nick def __sleep(self): print('from People') def eat(self): print('from eat')peo = People()peo.eat() # from eatpeo.__name() # 打印报错 'People' object has no attribute '__name'peo.__sleep() # 打印报错 'People' object has no attribute '__sleep'
如果要想访问有属性可以通过“_类名__私有属性”来使用
class People: __name = 'nick' peo = People()print(peo._People__name)
nick
封装的好处
- 数据封装:将数据隐藏起来这不是目的。隐藏起来然后对外提供操作该数据的接口,然后我们可以在接口附加上对该数据操作的限制,以此完成对数据属性操作的严格控制
- 封装方法:目的是隔离复杂度
私有模块
就是在模块内定义私有属性或函数如:_name = 'nick'
,在导入该模块时from module import *
无法导入该私有属性_name,若要导入则使用from module import _x
类的propertry特性
property装饰器用于将被装饰的方法伪装成一个数据属性,在使用时可以不用加括号而直接使用
# 没加property装饰器class People: def __init__(self, height, weight): self.height = height self.weight = weight def bmi(self): return self.weight/(self.height ** 2) peo = People(1.8, 70)print(peo.bmi())
21.604938271604937
class People: def __init__(self, height, weight): self.height = height self.weight = weight @property # 将装饰器后,将bmi函数伪装成一个数据属性 def bmi(self): return self.weight/(self.height ** 2) peo = People(1.8, 70)print(peo.bmi) # 不用加括号直接使用
21.604938271604937
setter 和 deleter
class People(): def __init__(self,height,weight): self.height = height self.weight = weight @property # 获取值的时候触发,你不需要加括号使用,不能加参数 def bmi(self): return self.weight/(self.height**2) @bmi.setter # 在修改bmi的时候触发,必须得加参数 def bmi(self, value): print(f'不能修改成{value}') @bmi.deleter # 在删除bmi的时候触发,不能加参数 def bmi(self): print('delter')peo = People(1.8,70)print(peo.bmi)print('*'*50)peo.bmi = 50print(peo.bmi)print('*'*50)del peo.bmiprint(peo.bmi)
21.604938271604937**************************************************不能修改成5021.604938271604937**************************************************delter21.604938271604937
类与对象的绑定方法与非绑定方法
绑定给谁,就将谁传给函数中的第一个参数作为self
class F: # 默认绑定给对象,只有对象能用,但是类也能使用,使用的时候必须得传参 def f1(self): print(self) # 绑定给类的方法,类能使用,对象也能使用,但是参数依然是类 @classmethod # 让被装饰的函数给类使用,约定俗成参数为cls def f2(cls): print(cls) # 什么都不绑定,非绑定方法,定义为普通的函数 @staticmethod def f3(self): print(self) f = F()f.f1() F.f1(111)print("*" * 30)f.f2()F.f2()print("*" * 30)f.f3('from f')F.f3('from F')
<__main__.F object at 0x000001CE0E2EDFD0>111************************************************************from ffrom F
总结
- 对象的绑定方法:没有加任何装饰的方法就是对象的绑定方法
- 类的绑定方法:加了@classmethod装饰器的方法就是类的绑定方法
- 非绑定方法:加了@staticmethod装饰器的方法就是非绑定方法,其实就是一个普通的函数