Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python与';导入为';变量赋值_Python_Import_Python Import - Fatal编程技术网

Python与';导入为';变量赋值

Python与';导入为';变量赋值,python,import,python-import,Python,Import,Python Import,以下两种说法有何不同?每种说法的后果是什么 导入为: from module.submodule import someclass as myclass 分配给变量: from module.submodule import someclass myclass = someclass 主要区别在于,在变量赋值示例中,someclass仍然可用作名称。这将导致导入具有相同名称的类型时出现问题 from datetime import datetime from arrow import dat

以下两种说法有何不同?每种说法的后果是什么

导入为:

from module.submodule import someclass as myclass
分配给变量:

from module.submodule import someclass
myclass = someclass

主要区别在于,在变量赋值示例中,
someclass
仍然可用作名称。这将导致导入具有相同名称的类型时出现问题

from datetime import datetime
from arrow import datetime  # problem!
要解决此问题,请执行以下操作:

from datetime import datetime
from arrow import datetime as arrow_datetime

这里给出的字节码输出是针对Python3.4的,但是生成字节码的代码应该适用于任何版本,并且相同的一般原则也适用

线束:

from dis import dis

def compile_and_dis(src):
    dis(compile(src, '<string>', 'exec'))
这是唯一一种只将一个名称(
myclass
)添加到当前
locals()
(即
\uuu dict\uuu
,对于模块中定义的所有内容,它将成为
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
)泄漏到本地名称空间中。如果导入和赋值不是连续的,那么在理论上可能会将名称重新用于其他用途,但是如果要隐藏名称,那么无论如何设计都很糟糕

注意字节码中无用的
存储\u名称
/
加载\u名称
循环(围绕一个不相关的
弹出顶部

案例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类似,但要求
模块。子模块
是一个模块

案例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个属性加载位于不同的位置,因此不同的变量泄漏到本地名称空间。

实际上是相同的事情。如果存在差异,请检查字节码。同样的事情,当我使用第二种方法(赋值到变量)时,您正在将其赋值到当前脚本的全局空间中的变量,因为其中一个无法显示快速定义或转到源代码,但是当我使用第一种方法时,它工作得很好。你知道为什么PyCharm不能在
someclass上显示快速定义或转到源代码吗?当我使用第二种方法(赋值到变量)时,某些属性或方法
,但当我使用第一种方法时,它工作得很好吗?这非常有用!
>>> 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