面对对象进阶2
类的封装
封装:隐藏属性或方法,外部无法使用,内部可以使用,再类定义阶段就执行了,真的想引用,就使__类名__属性名
隐藏模块内部的函数/变量_x:from module import *(无法导入),from module import _x(不合理)
@property:被 @property 装饰的函数会从函数变成属性,也就是说直接.函数名,不需要加括号使用
class People:
def __init__(self,pwd):
self.__pwd = pwd
@property #被property 装饰的函数会从函数变成属性
def pwd(self):
return f'无法获取你的密码'
p = People('123')
print(p.pwd) #无法获取你的密码
对属性这个封装有什么用:藏起来,保护了你的隐私,类内部的属性不想让其他人访问,
class F1: # F1类名
__count = 0 # __count属性名
f= F1()
print(f._F1__count) #如果真的要拿,_类名__属性去拿(不可能这样做)
#0
对方法封装有什么好处:精简了代码,你吃饭就使用chifan这个方法就行了,不需要去关心其他的操作,并且外部调用者也不知道你内部发生了什么
class Foo:
def f1(self):
print('FOO.f1')
def f2(self):
print('Foo.f2')
self.f1()
class Bar(Foo):
def f1(self):
print('Bar.f1')
foo = Bar()
foo.f2() #先从Bar对象中寻找f2,再从Bar类中寻找f2,再从Bar的父类中的对象进行查找f2,找到了,再从Bar对象中寻找f1,找到了
Foo.f2
Bar.f1
class Foo:
def __f1(self):
print('FOO.f1')
def f2(self):
print('Foo.f2')
self.__f1()
print(Foo.__dict__) #类中所有的方法和属性,使用时点出来
class Bar(Foo):
def __f1(self):
print('Bar.f1')
bar = Bar() #执行Bar类,Bar类继承了Foo父类,可以使用父类中的所有方法
bar.f2() #使用父类中f2的函数,由于__f1()函数,在定义阶段,就已经被封装了,会把私有属性__f1变成__Foo__f1,之后都不会做这种处理
{'__module__': '__main__', '_Foo__f1': <function Foo.__f1 at 0x00D538A0>, 'f2': <function Foo.f2 at 0x00D53C90>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}
Foo.f2
FOO.f1
class Foo():
__count = 0 #类的内部
foo = Foo()
print(foo)
foo.__y = 1 #类的外部
print(foo.__y)
<__main__.Foo object at 0x00B96B90>
1
类的property特性
@property:会让函数方法bmi()变成属性,我们就应该用@property。
@方法名.setter:被@方法名.setter装饰的函数,让这个函数方法bmi()可以进行属性一样的修改,所以@bmi.setter装饰器的函数方法必须是property装饰的函数方法名bmi(),而不可以是随意定义的函数名字,如果换成其他名字会报错,显示的就是该属性(实际是个函数)无法进行修改或删除
随意定义函数方法名是类属性方法使用property可以使用的
@方法名.deleter:被@方法名.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 = 50
print('*'*50)
del peo.bmi
21.604938271604937
**************************************************
你已经成功修改为50
**************************************************
delter
类与对象的绑定方法和非绑定方法
什么时候使用?
需要使用类做为参数的时候就得使用类绑定方法@classmethod
需要使用对象作为参数的时候就得使用对象绑定方法
既不需要类作为参数又不需要对象作为参数,使用费非绑定方法,@staticmethod
@classmethod让被装饰的函数给类使用,约定俗成参数为cls
绑定类的方法,类能使用,对象也可以使用,但是参数依然是类
@staticmethod什么都不绑定,非绑定方法,定义了普通的函数
class Foo:
#绑定给对象,只有对象能用,但是类也能使用,使用的时候必须得传参
def f1(self):
print(self)
@classmethod #让被装饰的函数给类使用,约定俗成参数为cls
#绑定给类的方法,类能使用,对象也可以使用,但是参数依然是类
@staticmethod #什么都不绑定,非绑定方法,定义了普通的函数
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) # 运行类中的函数,打印结果
<__main__.Foo object at 0x00B56BB0>
1111
**************************************************
<class '__main__.Foo'>
<class '__main__.Foo'>
**************************************************
2222
2222
python2中类属性调用的方法
对象的绑定方法:没有加任何装饰的方法就是对象的绑定方法
类的绑定方法:加了@classmethod装饰器的方法就是类的绑定方法
非绑定方法:加了staticmethod装饰器的方法就是非绑定方法,其实就是一个普通的函数
原文地址:https://www.cnblogs.com/zuihoudebieli/p/11219187.html