“导入为”与变量赋值之间的Python差异
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了“导入为”与变量赋值之间的Python差异,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3432字,纯文字阅读大概需要5分钟。
内容图文
以下两个陈述如何不同,每个陈述的后果是什么?
导入为:
from module.submodule import someclass as myclass
分配给变量:
from module.submodule import someclass
myclass = someclass
解决方法:
此处给出的字节码输出适用于Python 3.4,但生成字节码的代码应适用于任何版本,并且适用相同的一般原则.
马具:
from dis import dis
def compile_and_dis(src):
dis(compile(src, '<string>', 'exec'))
情况1:
>>> compile_and_dis('from module.submodule import someclass as myclass')
1 0 LOAD_CONST 0 (0)
3 LOAD_CONST 1 (('someclass',))
6 IMPORT_NAME 0 (module.submodule)
9 IMPORT_FROM 1 (someclass)
12 STORE_NAME 2 (myclass)
15 POP_TOP
16 LOAD_CONST 2 (None)
19 RETURN_VALUE
这是唯一一种只在当前locals()中添加一个名称(myclass)的方法(即__dict__,它将成为模块中定义的所有内容的globals()).它也是最短的字节码.
如果在module.submodule中找不到someclass,则此方法将引发ImportError.但是,它会尝试将module.submodule.someclass作为模块加载.
案例2:
>>> compile_and_dis('from module.submodule import someclass; myclass = someclass')
1 0 LOAD_CONST 0 (0)
3 LOAD_CONST 1 (('someclass',))
6 IMPORT_NAME 0 (module.submodule)
9 IMPORT_FROM 1 (someclass)
12 STORE_NAME 1 (someclass)
15 POP_TOP
16 LOAD_NAME 1 (someclass)
19 STORE_NAME 2 (myclass)
22 LOAD_CONST 2 (None)
25 RETURN_VALUE
这几乎与案例1完全相同,只是它将第二个名称(someclass)泄漏到本地名称空间中.如果导入和赋值不是连续的,那么你确实会冒着将名称重用于其他东西的理论风险,但是如果你是阴影名称,那么无论如何都要设计糟糕的设计.
请注意字节码中无用的STORE_NAME / LOAD_NAME循环(围绕不相关的POP_TOP).
案例3:
>>> compile_and_dis('from module import submodule; myclass = submodule.someclass')
1 0 LOAD_CONST 0 (0)
3 LOAD_CONST 1 (('submodule',))
6 IMPORT_NAME 0 (module)
9 IMPORT_FROM 1 (submodule)
12 STORE_NAME 1 (submodule)
15 POP_TOP
16 LOAD_NAME 1 (submodule)
19 LOAD_ATTR 2 (someclass)
22 STORE_NAME 3 (myclass)
25 LOAD_CONST 2 (None)
28 RETURN_VALUE
此方法将子模块泄漏到本地名称空间中.如果找不到类,它不会引发ImportError,而是在赋值期间引发AttributeError.它不会尝试将module.submodule.someclass作为模块加载(实际上甚至不关心module.submodule是否是模块).
案例4:
>>> compile_and_dis('import module.submodule as submodule; myclass = submodule.someclass')
1 0 LOAD_CONST 0 (0)
3 LOAD_CONST 1 (None)
6 IMPORT_NAME 0 (module.submodule)
9 LOAD_ATTR 1 (submodule)
12 STORE_NAME 1 (submodule)
15 LOAD_NAME 1 (submodule)
18 LOAD_ATTR 2 (someclass)
21 STORE_NAME 3 (myclass)
24 LOAD_CONST 1 (None)
27 RETURN_VALUE
这类似于案例3,但要求module.submodule是一个模块.
案例5:
>>> compile_and_dis('import module.submodule; myclass = module.submodule.someclass')
1 0 LOAD_CONST 0 (0)
3 LOAD_CONST 1 (None)
6 IMPORT_NAME 0 (module.submodule)
9 STORE_NAME 1 (module)
12 LOAD_NAME 1 (module)
15 LOAD_ATTR 2 (submodule)
18 LOAD_ATTR 3 (someclass)
21 STORE_NAME 4 (myclass)
24 LOAD_CONST 1 (None)
27 RETURN_VALUE
此方法类似于案例4,尽管2个属性加载位于不同的位置,因此不同的变量会泄漏到本地名称空间中.
内容总结
以上是互联网集市为您收集整理的“导入为”与变量赋值之间的Python差异全部内容,希望文章能够帮你解决“导入为”与变量赋值之间的Python差异所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。