python基础 day26 面向对象—super、内置函数property setter 反射
1、类的种类
-
新式类:继承object的类就是新式类,在py3中所有的类都是新式类,在py2中主动继承object的是新式类
-
经典类:只有py2中,不继承object的就是经典类
1、继承顺序
-
深度优先 经典类
-
广度优先 新式类
-
查看广度优先的顺序:类名.mro()
-
遵循C3算法
-
2、抽象类
-
为了约束规范子类必须实现父类的同名方法
-
3、归一化设计
4、多态
-
一个类表现出的多种形态,主要指的是一个子类的对象也是父类类型
二、今日内容
1、super
-
super是按照mro顺序来寻找当前类的下一个类
-
在python3中不需要传递参数
-
在python2中的新式类,需要主动传递参数(子类的名字,子类的对象) # super(D,self).func()
-
在单继承的程序中,super就是找父类
-
class User:
def __init__(self,age):
self.age = age
class VipUser(User):
def __init__(self,name,age,level,star_date):
super().__init__(age)
self.name = name
self.level = level
self.star_date = star_date
v = VipUser('太白',22,12,'2020-01-01')
print(v.__dict__)
class A:
def func(self):
print('in a')
class B(A):
def func(self):
super().func()
print('in b')
class C(A):
def func(self):
super().func()
print('in c')
class D(B,C):
def func(self):
super().func()
#super(D,self).func() #python 2中这样传递参数
print('in d')
D().func()
# D().func()
# D,B,C,A
# super是按照mro顺序来寻找当前类的下一个类
# 在py3中不需要传参数,自动就帮我们寻找当前类的mro顺序的下一个类中的同名方法
# 在py2中的新式类中,需要我们主动传递参数super(子类的名字,子类的对象).函数名()
# 这样才能够帮我们调用到这个子类的mro顺序的下一个类中的方法
# 在py2的经典类中,并不支持使用super来找下一个类
2、封装
-
定义: 就是把属性和方法装起来
-
广义上的封装
-
把属性和方法装起来,外面不能调用,要通过类的名字调用
-
-
狭义上的封装 :把属性和方法藏起来,外面不能调用,只能在内部调用
-
封装的语法 :给一个名字前面添加双下划线,会变成一个私有的
-
所有的私有的内容或名字,都不能在类的外部调用,只能在类的内部使用
-
私有的静态变量
#############私有静态变量###############
class Apple:
__County = '中国' #名称已改变 _Apple__County
def __init__(self,name,price):
self.name = name
a = Apple('alex',20)
print(Apple.__dict__) # '_Apple__County': '中国'
print(a.__dict__) #{'name': 'alex'}
# print(Apple.__County)
# print(a.__County) -
私有的实例变量
class Resister:
def __init__(self,name,pwd):
self.name = name
self.__pwd = pwd #名称已改变 _Resister__pwd
def get_pwd(self):
return self.__pwd
alex = Resister('alex',123)
print(alex.get_pwd())
print(alex.__dict__) #{'name': 'alex', '_Resister__pwd': 123}
# print(alex.__pwd) #无法查看 -
私有的绑定方法
##################私有的绑定方法######################
class Foo:
def __init__(self,name):
self.name = name
def __func(self): #'_Foo__func': <function Foo.__func at 0x000001DA26603E18>
print(self.name)
# print(Foo('alex').__func())
print(Foo.__dict__) -
私有的内容不能被继承,在私有化时,私有的名称已经发生变化,只有在本类中,才会替换成自己通过self调用的
class Resister:
def __init__(self,name,pwd):
self.name = name
self.__pwd = pwd #名称已改变 _Resister__pwd
def get_pwd(self):
return self.__pwd
alex = Resister('alex',123)
print(alex.get_pwd())
print(alex.__dict__) #{'name': 'alex', '_Resister__pwd': 123}
# print(alex.__pwd) #无法查看
class Foo:
def __init__(self):
self.func()
def func(self):
print('in Foo')
class Role(Foo):
def func(self):
print(' in role')
Role() #' in role'
class Foo:
def __init__(self):
self.__func()
def __func(self):
print('in Foo')
class Role(Foo):
def __func(self):
print(' in role')
Role() #' in Foo'
print(Foo.__dict__) # _Foo__func
print(Role.__dict__) # _Role__func
-
-
封装的原理
-
3、类中的三个装饰器(内置函数)
-
property :把一个方法伪装成属性
# class Apple:
# def __init__(self,name,price):
# self.name = name
# self.__price =price
# def price(self):
# return self.__price
# a = Apple('apple',220)
# print(a.name)
# print(a.price())
###############把一个方法伪装成属性######################
class Apple:
def __init__(self,name,price):
self.name = name
self.__price =price
-
-
classmethod
-
staticmechod
4、反射
-
hasattr :判断字符串是否在反射的对象中 存在True 不存在 False
-
getattr
-
几种情况
-
反射模块中的内容
-
反射本文件中的内容
-
反射对象的属性和绑定方法
-
反射类的静态变量
-
-
callable判断是否可被调用
-
实际例子-归一化设计
import sys
class Payment: ##这个类就是一个约束类,并且是一个抽象类
def pay(self,money):
raise NotImplementedError("必须实现一个同名函数pay")
class ApplePay:
def __init__(self,name):
self.name = name
def pay(self,money):
print(f'你通过{self.name}支付了{money}钱!')
class Wechat:
def __init__(self,name):
self.name = name
def pay(self,money):
print(f'你通过{self.name}支付了{money}钱!')
class Alipay:
def __init__(self,name):
self.name = name
def pay(self,money):
print(f'你通过{self.name}支付了{money}钱!')
#归一化设计
def pay(name,money,kind):
if hasattr(sys.modules['__main__'],kind): #判断对象是否在类中
if callable(getattr(sys.modules['__main__'],kind)): #判断实例化的对象是否可被调用
obj = getattr(sys.modules['__main__'],kind)(name) # ==obj.kind(name)
obj.pay(money)
pay('alex',200,'Wechat')
pay('wusir',200,'ApplePay')
#反射模块中的内容
print(getattr(sys.modules['__main__'],'Wechat'),Wechat) #<class '__main__.Wechat'> <class '__main__.Wechat'>
print(getattr(sys.modules['__main__'],'Wechat')('alex')) #== Wechat('alex')
#反射对象的属性和绑定方法
print(getattr(sys.modules['__main__'],'Wechat')('alex').name) # Wechat('alex').name
print(getattr(ApplePay,'pay')) # print(ApplePay.pay)
getattr(ApplePay('alex'),'pay')(200) #反射类中的绑定方法
ApplePay('alex').pay(2000)
import a
print(a.name)
print(getattr(a,'name'))#反射模块中的内容
print(getattr(a,'age')) #反射模块中的内容
from a import A
obj = A('alex')
print(obj.name)
print(getattr(A('wusir'),'name')) #反射模块中的实例变量
res = getattr(A("alex"),'func') #反射a模块中的class A
res() # in a 模块 in A 类
-