Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.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 - Fatal编程技术网

Python 为什么可以';我不能从模块别名导入吗?

Python 为什么可以';我不能从模块别名导入吗?,python,Python,我刚刚在python(2.7和3.x)中偶然发现了这种意想不到的行为: 哎呀 翻看一下,我看到sys.modules包含了真正的模块名(re或cPickle,但不是别名regexp或pickle。这解释了第二次导入失败的原因,但不是python模块名称解析以这种方式工作的原因,即以这种方式工作的规则和原理 注意:这被标记为的副本,与模块别名无关:问题中甚至没有提到别名(关于从包导入子模块)或者最上面的答案。虽然该问题的答案提供了与此问题相关的信息,但问题本身与IMHO并不相似。简而言之: 您可以

我刚刚在python(2.7和3.x)中偶然发现了这种意想不到的行为:

哎呀

翻看一下,我看到
sys.modules
包含了真正的模块名(
re
cPickle
,但不是别名
regexp
pickle
。这解释了第二次导入失败的原因,但不是python模块名称解析以这种方式工作的原因,即以这种方式工作的规则和原理

注意:这被标记为的副本,与模块别名无关:问题中甚至没有提到别名(关于从包导入子模块)或者最上面的答案。虽然该问题的答案提供了与此问题相关的信息,但问题本身与IMHO并不相似。

简而言之: 您可以这样考虑加载过程:

您可以以变量的形式将模块加载到程序中。您可以为使用模块的变量命名,但加载过程基于模块文件的名称,而不是“模块变量”


长版本:
import re
创建一个名为
re
的全局变量,该变量作为“模块门户”,提供使用模块操作的能力

最相似的是,
import re as regex
在名为
regex
的变量下创建这样一个“门户”

但是,当希望创建此类门户并将模块功能加载到其中时,导入器不会使用此类引用。相反,它会在python
\Lib
目录或当前工作目录中查找名为
re.py
文件(或您导入的模块的名称)

import
指令不处理变量,但像
#这样的文件在C中包含了
。它们有自己的“语法”,以及由解释器结构规定的指令集,在这种情况下,解释器结构将
re
解释为文件名而不是变量,并将
解释为
,用于规定模块“门户”的名称

这就是为什么
regex
re
门户的操作别名,而不是模块的导入别名(为此,您必须使用文件名)

  • 我使用了诸如“模块门户”和“操作别名”之类的术语,因为我没有找到任何标准术语。大多数模块和导入器机制都与解释器实现有关。例如,在CPython(开发人员普遍使用C API)中,为导入器创建模块(以
    PyObject
    s的形式)使用提供的模块规范,以及具有模块属性的模块实例创建的和函数。这些可在中查看

  • 当我提到术语“门户”作为引用由
    import
    语句创建的变量的一种方式时,我的意思是将其称为静态门户,而不是动态门户。模块文件中的更改不会反映在已导入它的运行程序中(只要它没有重新加载),因为它将加载模块的副本并使用它,而不是在遇到需要时向模块文件请求操作


以下是变量加载的实时方式:

>>> import re
>>> re
<module 're' from 'C:\\Programs\\Python35\\lib\\re.py'>
>>> import re as regex
>>> regex
<module 're' from 'C:\\Programs\\Python35\\lib\\re.py'>
>>重新导入
>>>再
>>>以正则表达式形式导入re
>>>正则表达式

您可以看到
re
是引用的模块,它是从
C:\Programs\Python35\lib\re.py
文件中加载的(可能会根据python的安装位置而变化).

当使用from import时,python会尝试在from文件中查找以导入您所请求的内容。这可能会更清楚

import re as regexp

from regexp import search 

这本质上要求python查找一个无法找到的名为“regexp”的文件。这就是别名不起作用的原因。

您不能将导入语句中的模块名视为变量。如果是这种情况,您的初始导入肯定会失败,因为
re
尚未声明变量。基本上,导入语句是sema它是一种有自己规则的陈述

其中一条规则是:写入的模块名称被理解为一个字符串。也就是说,它不查找名为
re
的变量,而是直接使用字符串值
're'
作为所需的模块名称。然后,它搜索具有此名称的模块/包(文件),并进行导入

<>这是唯一的情况(<强>编辑:,参见评论中的讨论…),在这种行为被看到的语言中,这是混淆的原因。请考虑这个备选语法,这与Python语言的其余部分更为一致:

import 're'
# Or alternatively
module_name = 're'
import module_name

这里,在import语句中假设变量展开。正如我们所知,这不是为import语句实际选择的语法。我们可以讨论哪种语法更好,但上述语法肯定与语言的其他语法更协调。

要得到明确的答案,您必须询问设计人员但是,我认为你问错了问题

问题不应该是:为什么要这样做?“但是,应该是,按照你所问的方式做有什么好处?当然可以,但为什么要这样做

正如
import
语句非常简单和直观,您给它一个文件名,它会尝试查找并加载它。您甚至会喜欢
As
from
但是,概念很简单,您编写文件名,然后任其发展

唯一的成就是让事情变得更复杂,这可能会混淆它,让它更难理解import re as regexp from regexp import search
import 're'
# Or alternatively
module_name = 're'
import module_name