Python中强大的动态类型特性,以方法调用为例
在研究大佬的项目时,从一行行代码溯源,拨茧抽丝的过程中,发现了方法调用的“神奇之处”
具体情况如下:
1. 在类Trainer中名为run等方法中有加载预训练好的模型的load方法
2. load()方法依旧是类方法中的一个,在load方法中有具体的load_self()方法
3. load_self()定义在另一个py文件models中,具体来说,models.py文件下有多个类中均定义了方法load_self()(共3个)
4. 所以当在class Trainer-->load()-->load_self()的调用中,会指向不同的三个类下的同名方法,在这个案例中三各类是继承于同一个“父亲”(nn.Module)
问题来了,当一个不属于该类的实例对象能使的动其他类下定义的方法吗(即使是同名的)
我们编写一个方法测试一下:
具体的思路是在test.py文件中,编写类方法,在test2.py中编写相关代码调用
首先是test.py
import torch.nn as nn class Cnn(nn.Module): def __init__(self, model): self.model = model def loading(self): print("Cnn") class Rnn(nn.Module): def __init__(self, model): self.model = model def loading(self): print("Rnn") class Vae(nn.Module): def __init__(self, model): self.model = model def loading(self): print("Vae") class Svm(): def __inot__(self, model): self.model = model def loading(self): print("Vae")
为了还原项目中的发现,这里一些继承和命名有借鉴源项目,细节不重要
然后是test2.py
只要是还原源项目中的情况,细节不重要
class Use(): def __init__(self, model): self.model = model def c(self): self.model.loading()
综上,在调用loading()方法时指向了四个”位置“
在方法实现界面,也有相应的提示
实验
当其中的一个类如Cnn的实例化,可以调用其它的类的方法,这样可能会自动定位到自己类下的方法,所以把Cnn类中的loding方法注释掉
model = Cnn() use = Use(model) use.c()
结果:
使用Rnn(带有loading方法)结果
总结
实例化哪个对象,类内部的方法还是要实现的,我所研究的项目的源代码应该是出现了一些bug,但是那个比较复杂,跑通可以进一步验证。在这个小实验中可以看到,在动态绑定同名方法中,如何实例化方法就链接到哪个方法中,即所谓的执行时才确定