python中import module 和 from module import * 是一样的吗?
在开发的过程中碰到了一个有趣的问题。看下面这段代码:
LOCAL = None try: from local_setting import * except ImportError as e: logging.exception(e) pass # 这里只有线上才会传LOG_FILE print("Local = " + str(LOCAL))
local_setting.py
LOCAL = True print("LOCAL =" + str(LOCAL))
print的结果为:
None LOCAL =True Local = True
说明local_setting.py中的LOCAL的namespace和主程序是一样的(这里是不是有点奇怪)。
然后把 from local_setting import * 改成import local_setting,执行
None LOCAL =True Local = None
这就是说local_setting.py中的LOCAL的namespace和主程序中的LOCAL又不一样了。
查了一下stackoverflow,有人这么回答:
There's a hell of a difference between importing specific named identifiers 'from module import X,Y,Z vs 'from module import *. The latter pollutes your namespace and can give unpredictable results depending on what's going on in module. Worse still is doing from module import * with multiple modules. – smci
有人回答:
Even though many people already explained about import vs import from, I want to try to explain a bit more about what happens under the hood, and where all the places it changes are. import foo: Imports foo, and creates a reference to that module in the current namespace. Then you need to define completed module path to access a particular attribute or method from inside the module. E.g. foo.bar but not bar from foo import bar: Imports foo, and creates references to all the members listed (bar). Does not set the variable foo. E.g. bar but not baz or foo.baz from foo import *: Imports foo, and creates references to all public objects defined by that module in the current namespace (everything listed in __all__ if __all__ exists, otherwise everything that doesn't start with _). Does not set the variable foo. E.g. bar and baz but not _qux or foo._qux. Now let’s see when we do import X.Y: >>> import sys >>> import os.path Check sys.modules with name os and os.path: >>> sys.modules['os'] <module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'> >>> sys.modules['os.path'] <module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'> Check globals() and locals() namespace dicts with os and os.path: >>> globals()['os'] <module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'> >>> locals()['os'] <module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'> >>> globals()['os.path'] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'os.path' >>> From the above example we found that only os is inserted in the local and global namespace. So, we should be able to use: >>> os <module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'> >>> os.path <module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'> >>> But not path. >>> path Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'path' is not defined >>> Once you delete the os from locals() namespace, you won't be able to access os as well as os.path even though they exist in sys.modules: >>> del locals()['os'] >>> os Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'os' is not defined >>> os.path Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'os' is not defined >>> Now let's talk about import from: from: >>> import sys >>> from os import path Check sys.modules with os and os.path: >>> sys.modules['os'] <module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'> >>> sys.modules['os.path'] <module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'> We found that in sys.modules we found as same as we did before by using import name OK, let's check how it looks like in locals() and globals() namespace dicts: >>> globals()['path'] <module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'> >>> locals()['path'] <module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'> >>> globals()['os'] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'os' >>> You can access by using name path not by os.path: >>> path <module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'> >>> os.path Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'os' is not defined >>> Let's delete 'path' from locals(): >>> del locals()['path'] >>> path Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'path' is not defined >>> One final example using an alias: >>> from os import path as HELL_BOY >>> locals()['HELL_BOY'] <module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'> >>> globals()['HELL_BOY'] <module 'posixpath' from /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'> >>> And no path defined: >>> globals()['path'] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'path' >>>
也就是说 from module import * 这种是把import里的对象放在主程序的namespace的。
https://stackoverflow.com/questions/710551/use-import-module-or-from-module-import
喜欢艺术的码农