Python中继承多态为何依赖导入方式?
为什么Python中继承多态的表现会依赖导入方式?
原始代码文件
base.py
class Base(): def method(self): print('Base Class') object = Base()
main.py(原始版本)
from base import object def main(): object.method() if __name__ == '__main__': main()
test.py
import main import base class Derived(base.Base): def method(self): print('Derived Class') base.object = Derived() main.main()
运行test.py的输出:
$ python3.8 test.py Base Class
修改后的代码与结果
修改后的main.py
import base def main(): base.object.method() if __name__ == '__main__': main()
修改后的输出:
$ python3.8 test.py Derived Class
核心原因:Python的名字绑定机制
这和多态本身无关,问题出在导入时的名字绑定逻辑:
第一种导入方式:
from base import object
当main.py用from base import object时,相当于在main模块的命名空间里,创建了一个直接指向base.py初始Base()实例的变量object。
后续test.py里修改base.object = Derived(),只是更新了base模块命名空间中object的指向,但main模块里的object变量依然绑定着最初的Base()实例,完全不受影响。所以调用main.main()时,执行的还是旧实例的method方法。第二种导入方式:
import base后使用base.object
这种情况下,main模块没有自己的object变量,每次调用base.object.method()时,都会实时去base模块的命名空间里查找object这个名字。
当test.py把base.object替换成Derived()实例后,main模块再访问base.object时,拿到的就是新实例,自然会调用Derived类的method方法。
总结:
from X import Y是把Y的当前引用复制到当前模块,后续X中Y的变化不会同步到当前模块的Y。import X后使用X.Y是每次都去X模块的命名空间查找Y,能实时获取Y的最新引用。
内容的提问来源于stack exchange,提问作者gaurav
相关产品推荐
相关产品推荐

