Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
479 views
in Technique[技术] by (71.8m points)

python - Why can't I import from a module alias?

I just stumbled across this unexpected behavior in python (both 2.7 and 3.x):

>>> import re as regexp
>>> regexp
<module 're' from '.../re.py'>
>>> from regexp import search
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named 'regexp'

Of course from re import search succeeds, just as it would have before I created the alias. But why can't I use the alias regexp, which is now a known module, as a source for importing names?

This sets you up for a nasty surprise whenever there are multiple variants of a module: Say I am still using Python 2 and I want to use the C version of pickle, cPickle. If I then try to import a name from pickle, it will be fetched from the simple pickle module (and I won't notice since it doesn't throw an error!)

>>> import cPickle as pickle
>>> from pickle import dump
>>> import inspect
>>> inspect.getsourcefile(dump)
'.../python2.7/pickle.py'    # Expected cPickle.dump 

Oops!

Poking around I see that sys.modules includes the real module name (re or cPickle, but not the alias regexp or pickle. That explains how the second import fails, but not why python module name resolution works this way, i.e. what the rules and rationale are for doing it this way.

Note: This was marked as a duplicate of a question that has nothing to do with module aliasing: aliasing is not even mentioned in the question (which is about importing submodules from a package) or the top answers. While the answers to that question provide information relevant to this question, the questions themselves are not even similar IMHO.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In short:

You can think of the loading process in that way:

You can load a module into your program, in the form of a variable. You can name the variable for using the module whatever you want. But, the loading process, is based on the name of the module's file, not "module variables".


Long version:

import re creates a global variable named re that serves as the "module portal", in the way it provides the ability to use the module operations.

Most alike, import re as regex creates such a "portal" under the variable named regex.

But, when looking to create such portal and load the module functionality into it, the importer does not use such references. Instead, it looks for the module in your python Lib directory, or your current working directory, as a file named re.py (or whatever is the name of the module you import).

The import instructions does not address variables, but files, like #include<stdio.h> in C. They have their "own syntax", and set of instructions, as ruled by the interpreter structure, which is, to that case, the interpretation of re as a file name rather than a variable and as for ruling the name of the module "portal".

That is why regex is an operation alias for the portal for re, but not an importation alias for the module (for that purpose you'll have to use the name of the file).

  • I have used terms like "module portal" and "operation alias" since I have not found any standard terms for these. Most of the modules and importer mechanics is related to the interpreter implementation. In CPython (where the usage of the C API is common among developers), for example, create_module creates modules for the importer (in the form of PyObjects) using the provided specifications for the module, and the PyModule_NewObject and PyModule_New functions for the module instance creation that bears the module attributes. These can be viewed in the C API modules decumentation.

  • When I mentioned the term "portal" as a way to reference the variable created by the import statement, I meant to refer to it as a static portal, not a dynamic one. A change in the module file will not reflect in a running program that already imported it (as long as it didn't reload it), as it will load a copy of the module and use it, rather than asking the module file for the operations when encountering need.


Here is pretty much how the variable loading goes realtime:

>>> 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'>

You can see that re is the module referenced, and it was loaded from the file C:ProgramsPython35lib e.py (may change depending on where your python is installed).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...