# 医院类和病患类demo
class hospital():
'''
address:医院地址
patient:将病患对象传入这个形参中
'''
def __init__(self,name,address,patient):
self.name = name
self.address = address
self.patient = patient
def fun(self):
print("{}接收{}病患,现在状态为{}".format(self.name,self.patient.name,self.patient.status))
if self.patient.status != "发烧":
print("不是新冠,放行。进一步检查...")
else:
print("{}病患状态为{},被诊断为新冠,立即治疗".format(self.patient.name,self.patient.status))
class disease():
'''
status:病患状态
hospital:将医院对象传入这个形参中
'''
def __init__(self,name,age,sex,status,hospital):
self.name = name
self.age = age
self.sex = sex
self.status = status
self.hospital = hospital
def goTohospital(self):
print("{0}今年{1}岁了,现在状态为{2},前往{3}看病".format(self.name,self.age,self.status,self.hospital.name))
# 实例化一个病患,并将医院对象传入病患对象中
'''
这里有个疑问,按照解释性编译应该会报hos未定义的错的,但是Jupyter没有报
我试了一下Python Shell编译确实报了hos未定义
个人认为是Jupyter使用了魔法或者什么咒语
'''
diseaser = disease("路人甲",18,"男","发烧",hos)
# 实例化一家医院,并将病患对象传入医院对象中
hos = hospital("人民医院","江苏省徐州市人民广场炸鸡店隔壁",diseaser)
# 病患去医院途中
diseaser.goTohospital()
# 医院诊断病患
hos.fun()
路人甲今年18岁了,现在状态为发烧,前往人民医院看病
人民医院接收路人甲病患,现在状态为发烧
路人甲病患状态为发烧,被诊断为新冠,立即治疗
上面是在构造函数中初始化其他对象的,还可以通过下面这样的方式这样先把对象实例化,然后再赋值,就不会报未定义的错了,我试了一下,确实没报错。
obj1 = 对象实例化
obj2 = 对象实例化
obj1.obj2 = obj2
obj2.obj1 = obj1
这样就1对象中有2对象的属性,2对象中也有1对象中的属性了
调用函数格式如下
对象1.对象2.对象2的函数或属性
obj1.obj2.obj2Fun()
obj2.obj1.obj1Fun()
__bases__
:返回一个类的基类,元组类型__mro__
:返回类的方法解析顺序# 列一:
class Fu():
def fun1(self):
print("I'm fun1 in Fu")
def fun2(self):
print("I'm fun2 in Fu")
class Zi1():
def fun2(self):
print("I'm fun2 in Zi1")
# Zi2继承Zi1
class Zi2(Zi1):
def fun1(self):
print("I'm fun1 in Zi2")
zi2 = Zi2()
zi2.fun1()
zi2.fun2()
print("-"*15)
# 打印Zi2类的继承关系,返回一个元组
print(Zi2.__bases__)
# 注意这一步,修改了Zi2类的继承关系
Zi2.__bases__ = (Fu,)+Zi2.__bases__
print(Zi2.__bases__)
print("-"*15)
zi2.fun1()
zi2.fun2()
I'm fun1 in Zi2
I'm fun2 in Zi1
---------------
(<class '__main__.Zi1'>,)
(<class '__main__.Fu'>, <class '__main__.Zi1'>)
---------------
I'm fun1 in Zi2
I'm fun2 in Fu
观察上面的代码,发现可以通过修改Zi2类的__bases__
值实现动态修改一个类的继承关系。如上面Zi2.__bases__=(Fu,)
修改为Zi2.__bases__=(Fu,Zi1)
实例调用fun2函数就由调用Zi1类中的fun2()变为调用Fu类中的fun2()函数
这和MRO的顺序规则是一样的,在前面的类中的方法会覆盖后面类中与其相同名称的方法或属性
但是有一个隐患,如果改了类的继承关系,而这个类有多个实例,则这些实例都会被影响,所以可以通过修改实例的__dict__
来动态加载函数
# 例二和例一差不多:
# 首先定义一个更改类继承关系的函数
def mixin(willChange_class,Mixin_class,flag = 0):
if flag:
# 将Mixin类动态添加到一个类的继承关系中,并列在继承顺序首位
willChange_class.__bases__ = (Mixin_class,) + willChange_class.__bases__
elif Mixin_class not in willChange_class.__bases__:
# 与上一句意思差不多,只是类的继承顺序不一样,可看下面a的例子
willChange_class.__bases__ += (Mixin_class,)
else:
print("无操作")
a = (1,)
a = (2,)+(1,)
print(a)
(2, 1)
a = (1,)
a += (2,)
print(a)
(1, 2)
class A():
def fun1(self):
print("在A类中的fun1函数")
class D_Mixin():
def fun4(self):
print("在D_Mixin类中的fun4函数")
class B(A):
def fun2(self):
print("在B类中的fun2函数")
class C(A):
def fun3(self):
print("在C类中的fun3函数")
# 先看一下C的继承关系
c_obj = C()
print(C.__bases__)
# 因为C类继承A类,可以调用A类中的fun1()方法
c_obj.fun1()
# 调用上面的mixin函数更改C类继承关系
mixin(C,D_Mixin,flag=1)
print(C.__bases__) # 可以看见,C类优先继承了D_Mixin类
print(C.__mro__) # 可以看见,C类的方法解析顺序是C -> D_Mixin -> A -> object
# 现在可以调用D_Mixin中的fun4()方法了
c_obj.fun4()
print("-"*30)
# 下面更改一下B类的继承顺序
# 先看一下B类的继承关系和方法解析顺序
print("B类继承关系更改前:")
print(B.__bases__)
print(B.__mro__)
# 调用mixin()方法更改继承顺序
mixin(B,D_Mixin)
print("B类继承关系更改后:")
print(B.__bases__)
print(B.__mro__)
# 可以发现B类的继承关系改为(A,D_Mixin)且D_Mixin类没有优先放在第一位,而是末尾添加
(<class '__main__.A'>,)
在A类中的fun1函数
(<class '__main__.D_Mixin'>, <class '__main__.A'>)
(<class '__main__.C'>, <class '__main__.D_Mixin'>, <class '__main__.A'>, <class 'object'>)
在D_Mixin类中的fun4函数
------------------------------
B类继承关系更改前:
(<class '__main__.A'>,)
(<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
B类继承关系更改后:
(<class '__main__.A'>, <class '__main__.D_Mixin'>)
(<class '__main__.B'>, <class '__main__.A'>, <class '__main__.D_Mixin'>, <class 'object'>)
def mixin(willChange_class,Mixin_class,flag = 0):
if flag:
willChange_class.__bases__ = (Mixin_class,) + willChange_class.__bases__
elif Mixin_class not in willChange_class.__bases__:
willChange_class.__bases__ += (Mixin_class,)
else:
print("无操作")
class A():
def fun1(self):
print("在A类中的fun1函数")
class D_Mixin():
def fun4(self):
print("在D_Mixin类中的fun4函数")
class B(A):
def fun2(self):
print("在B类中的fun2函数")
class C(A):
def fun3(self):
print("在C类中的fun3函数")
c_obj = C()
print(C.__bases__)
c_obj.fun1()
mixin(C,D_Mixin,flag=1)
print(C.__bases__)
print(C.__mro__)
c_obj.fun4()
print("-"*30)
print("B类继承关系更改前:")
print(B.__bases__)
print(B.__mro__)
mixin(B,D_Mixin)
print("B类继承关系更改后:")
print(B.__bases__)
print(B.__mro__)