Use 'import module' or 'from module import'?

前端 未结 19 2121
一向
一向 2020-11-21 07:47

I\'ve tried to find a comprehensive guide on whether it is best to use import module or from module import. I\'ve just started with Python and I\'m

相关标签:
19条回答
  • 2020-11-21 08:19

    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'
    >>>
    
    0 讨论(0)
提交回复
热议问题