简体   繁体   English

为什么不能从内存中的模块导入

[英]Why can I not import from a module in memory

I can do import module as md 我可以import module as md

I can do import module.submodule as smd 我可以import module.submodule as smd

So why can't I do either of the following? 那么,为什么不能执行以下任一操作?

import module as md
import md.submodule as smd

or 要么

import module as md
from md import submodule as smd

Asked differently: why do I have to use the long name, rather than the name I gave it? 提出不同的问题:为什么我必须使用长名称而不是我给的名字?

After the first line, md should just be a first-class object in memory. 在第一行之后, md应该只是内存中的一流对象。 Why was the decision made not to let me import from this object? 为什么做出不让我从该对象导入的决定? (Especially considering the code "reads" as if module is already available in memory at the start - the Python guys explicitly chose for this syntax as opposed to something like md = import("module") ) (特别考虑代码“ reads”,好像module就已经在内存中可用了-Python的人明确选择了这种语法,而不是像md = import("module")

Because md may be an existing module, and since python is permissive, it will let you replace its name but you can still import it whenever you want, example: 因为md可能是现有模块,并且因为python是允许的,所以它可以让您替换其名称,但仍然可以随时导入它,例如:

>> import urllib2 as json

This will work, even though json is a real module and could be imported, what if you wanted to import it afterwards ? 即使json是一个真实的模块并且可以导入,这仍然可以工作,如果您以后想要导入它,该怎么办?

so when you will check json in this case 所以在这种情况下何时检查json

>> json
>> <module 'urllib2' from '/usr/lib/python2.7/urllib2.pyc'>

it is pointed to urllib2 but you can still import submodules of real json: 它指向urllib2,但是您仍然可以导入真实json的子模块:

>> from json import tool as tl

json will remain the same as before, which is urllib2. json将与以前相同,即urllib2。 but you can get it back 但你可以找回来

>> import json
>> <module 'json' from '/usr/lib/python2.7/json/__init__.pyc'>

So to answer your question, it is probably a way to make it still accessible to get modules from your supposed alias ( if it is a name of a real module ). 因此,要回答您的问题,这可能是一种使其仍然可以从假定的别名(如果它是真实模块的名称)中获取模块的方法。

Just by having a look at what the module dis and its documentation say might clarify what happens in background. 仅通过查看模块dis及其文档中的内容,就可以弄清后台发生了什么。

>>> def g():
...   import numpy as np
... 
>>> def h():
...   import np.ma as ma # note: np is not defined!
... 
>>> dis.dis(g)
  2       0 LOAD_CONST               1 (-1)
          3 LOAD_CONST               0 (None)
          6 IMPORT_NAME              0 (numpy)
          9 STORE_FAST               0 (np)
         12 LOAD_CONST               0 (None)
         15 RETURN_VALUE        
>>> dis.dis(h)
  2       0 LOAD_CONST               1 (-1)
          3 LOAD_CONST               0 (None)
          6 IMPORT_NAME              0 (np.ma)
          9 STORE_FAST               0 (np)
         12 LOAD_CONST               0 (None)
         15 RETURN_VALUE        

To quote the docs, IMPORT_NAME means: 要引用文档, IMPORT_NAME的意思是:

Imports the module co_names[namei]. 导入模块co_names [namei]。 TOS and TOS1 are popped and provide the fromlist and level arguments of __import__() . 弹出TOS和TOS1并提供__import__()的fromlist和level参数。 The module object is pushed onto the stack. 模块对象被压入堆栈。 The current namespace is not affected: for a proper import statement, a subsequent STORE_FAST instruction modifies the namespace. 当前的名称空间不受影响:对于正确的import语句,随后的STORE_FAST指令将修改该名称空间。

(TOS and TOS1 are the top-of-Stack and the the second top-most stack item.) (TOS和TOS1是堆栈顶部,第二个堆栈顶部第二项。)

Therefore, I would say that the reason it doesn't work is that the import statement works if and only if the token you pass is really a module name (not an object), as this will be passed to the __import__ function, which requires a module name, not a reference/variable/whatever. 因此,我想说它不起作用的原因是,仅当您传递的令牌确实是模块名称(而不是对象)时, import语句才有效,因为它将被传递给__import__函数,这需要模块名称,而不是引用/变量/任何名称。

More information about how this works can be found on the __import__ documentation page. 有关此工作原理的更多信息,请参见__import__文档页面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM