目录
- 第四十三篇 面向对象进阶2
- 一、类的封装
- 二、类的property特性
- 三、类与对象的绑定方法及非绑定方法
- 四、总结
- 1.封装:隐藏属性或方法,外部无法使用,内部可以使用,在类定义阶段就执行了,真的想引用,就使用_类名__属性名
- 2.隐藏模块内的函数/变量_x:from module import *(无法导入), from module import _x(不合理)
- 3.@property:被 @property 装饰的函数会从函数变成属性,也就是说直接.函数名,不需要加括号使用
- 4.@方法名.setter:被 @方法名.setter 装饰的函数,方法名修改,会执行这个装饰的函数
- 5.@方法名.deleter:被 @方法名.deleter 装饰的函数,方法名删除,会执行这个装饰的函数
- 6.python2中类属性调用的方法
- 7.对象的绑定方法:没有加任何装饰的方法就是对象的绑定方法
- 8.类的绑定方法:加了@classmethod装饰器的方法就是类的绑定方法
- 9.非绑定方法:加了@staticmethod装饰器的方法就是非绑定方法,其实就是一个普通的函数
第四十三篇 面向对象进阶2
一、类的封装
封装:打包,封起来,装起来
1.封装分为两个层面
1.第一个层面:对象能拿到类的东西,但是类能拿到对象的东西吗?这里就存在一层封装
class Foo():
count = 0
print(count)
f = Foo()
print(f.count) # 0
f.name = 'nick' # 对对象进行了封装
print(Foo.name)
2.第二个层面的:内部可以使用,外部不可以使用,在你需要封装的属性前面加上__
class People():
__love_people = 'male'
print('in',love_people)
def __nawan(self):
print('nawan')
def __nakuaizi(self):
print('nakuaizi')
def __chifan(self):
print('chifan')
def chifan_all(self):
self.__nawan()
self.__nakuaizi()
self.__chifan()
print('out',People.__f1)
p = People()
print('out',p.nawan())
print('out',p.nakuaizi())
print('out',p.chifan())
print('out',p.chifan_all())
3.对属性这个封装有什么用:藏起来了,保护了你的隐私,类内部的属性不想让其他人访问
4.对方法封装有什么好处:精简了代码,你吃饭就使用chifan这个方法就行了,不需要去关心其他的操作,并且外部调用者也不知道你内部发生了什么
2.应用
print('*'*50)
class People:
def __init__(self,pwd):
self.__pwd = pwd
@property # 方法不用加括号使用
def pwd(self):
return f'无法获取你的密码'
p = People('123')
print(p.pwd)
print(p.pwd)
class F1:
__count = 0
f = F1()
print(f._F1__count) # 如果你真的要拿,_类名__属性去拿(不可能这样做)
class Foo:
def f1(self):
print('FOO.f1')
def f2(self): # foo
print('Foo.f2')
self.f1()
class Bar(Foo):
def f1(self):
print('Bar.f1')
foo = Bar()
foo.f2() # Foo.f2 # Bar.f1
class Foo:
def __f1(self): # _Foo__f1
print('FOO.f1')
def f2(self): # foo
print('Foo.f2')
self.__f1() # _Foo__f1
print(Foo.__dict__)
class Bar(Foo):
def __f1(self): # _Bar__f1
print('Bar.f1')
bar = Bar()
bar.f2() # Foo.f2
# 封装其实在定义阶段就以己经执行了,会把私有属性__f1变成_Foo__f1,之后都不会做这种处理
class Foo():
__count = 0
foo = Foo()
print(foo)
foo.__y = 1
print(foo.__y)
二、类的property特性
1. BMI(Body Mass Index):身体体质指数
男性体脂>25%,女性>33%是诊断为肥胖的标准
class People():
def __init__(self,height,weight):
self.height = height
self.weight = weight
@property
def bmi(self):
return self.weight/(self.height**2)
peo = People(1.8,70)
print(peo.height)
print(peo.bmi())
print(peo.bmi)
2.装饰器用法(只在Python3中使用)
1.property一般用在:本来是方法,但是他应该是属性的时候,我们就应该property
2.setattr 和 delattr
3.setattr 和 delattr这两个方法只能对属性修改和删除,也就是在使用了property之后使用
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 = 50
print('*'*50)
del peo.bmi
类属性用法(Python2的)
三、类与对象的绑定方法及非绑定方法
1.绑定方法:绑定的方法
class Foo:
# 绑定给对象,只有对象能用,但是类也能使用,使用的时候必须得传参
def f1(self):
print(self)
@classmethod # 让被装饰的函数给类使用,约定俗称参数为cls
# 绑定给类的方法,类能使用,对象也可以使用,但是参数依然是类
def f2(cls):
print(cls)
# 什么都不绑定的,非绑定方法,定义了普通的函数
@staticmethod
def f3(self):
print(self)
f = Foo()
f.f1()
Foo.f1(1111)
print('*' * 50)
Foo.f2()
f.f2()
print('*'*50)
Foo.f3(2222)
f.f3(2222)
2.什么时候使用?
- 这个方法需要使用类做为参数的时候就得使用类绑定方法,@classmethod
class A:
def __init__(self,name):
self.name = name
@classmethod
def cla_pri(cls):
print(f'{cls.__name__},{cls}')
class B(A):
pass
A.cla_pri()
B.cla_pri()
x = B('x')
x.cla_pri()
'''
A,<class '__main__.A'>
B,<class '__main__.B'>
B,<class '__main__.B'>
'''
- 这个方法需要使用对象作为参数的时候就得使用对象绑定方法
- 这方法即不需要类作为参数又不需要对象作为参数,使用非绑定方法,@staticmethod
四、总结
1.封装:隐藏属性或方法,外部无法使用,内部可以使用,在类定义阶段就执行了,真的想引用,就使用_类名__属性名
2.隐藏模块内的函数/变量_x:from module import *(无法导入), from module import _x(不合理)
3.@property:被 @property 装饰的函数会从函数变成属性,也就是说直接.函数名,不需要加括号使用
4.@方法名.setter:被 @方法名.setter 装饰的函数,方法名修改,会执行这个装饰的函数
@bmi.setter
def set_bmi():
print('setter')
peo.bmi = 40
5.@方法名.deleter:被 @方法名.deleter 装饰的函数,方法名删除,会执行这个装饰的函数
@bmi.deleter
def del_bmi():
print('deleter')
del peo.bmi