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

前端 未结 19 2156
一向
一向 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:11

    Both ways are supported for a reason: there are times when one is more appropriate than the other.

    • import module: nice when you are using many bits from the module. drawback is that you'll need to qualify each reference with the module name.

    • from module import ...: nice that imported items are usable directly without module name prefix. The drawback is that you must list each thing you use, and that it's not clear in code where something came from.

    Which to use depends on which makes the code clear and readable, and has more than a little to do with personal preference. I lean toward import module generally because in the code it's very clear where an object or function came from. I use from module import ... when I'm using some object/function a lot in the code.

    0 讨论(0)
  • 2020-11-21 08:13

    There's another detail here, not mentioned, related to writing to a module. Granted this may not be very common, but I've needed it from time to time.

    Due to the way references and name binding works in Python, if you want to update some symbol in a module, say foo.bar, from outside that module, and have other importing code "see" that change, you have to import foo a certain way. For example:

    module foo:

    bar = "apples"
    

    module a:

    import foo
    foo.bar = "oranges"   # update bar inside foo module object
    

    module b:

    import foo           
    print foo.bar        # if executed after a's "foo.bar" assignment, will print "oranges"
    

    However, if you import symbol names instead of module names, this will not work.

    For example, if I do this in module a:

    from foo import bar
    bar = "oranges"
    

    No code outside of a will see bar as "oranges" because my setting of bar merely affected the name "bar" inside module a, it did not "reach into" the foo module object and update its "bar".

    0 讨论(0)
  • 2020-11-21 08:13

    To add to what people have said about from x import *: besides making it more difficult to tell where names came from, this throws off code checkers like Pylint. They will report those names as undefined variables.

    0 讨论(0)
  • 2020-11-21 08:14

    As Jan Wrobel mentions, one aspect of the different imports is in which way the imports are disclosed.

    Module mymath

    from math import gcd
    ...
    

    Use of mymath:

    import mymath
    mymath.gcd(30, 42)  # will work though maybe not expected
    

    If I imported gcd only for internal use, not to disclose it to users of mymath, this can be inconvenient. I have this pretty often, and in most cases I want to "keep my modules clean".

    Apart from the proposal of Jan Wrobel to obscure this a bit more by using import math instead, I have started to hide imports from disclosure by using a leading underscore:

    # for instance...
    from math import gcd as _gcd
    # or...
    import math as _math
    

    In larger projects this "best practice" allows my to exactly control what is disclosed to subsequent imports and what isn't. This keeps my modules clean and pays back at a certain size of project.

    0 讨论(0)
  • 2020-11-21 08:15

    This is my directory structure of my current directory:

    .  
    └─a  
       └─b  
         └─c
    
    1. The import statement remembers all intermediate names.
      These names have to be qualified:

      In[1]: import a.b.c
      
      In[2]: a
      Out[2]: <module 'a' (namespace)>
      
      In[3]: a.b
      Out[3]: <module 'a.b' (namespace)>
      
      In[4]: a.b.c
      Out[4]: <module 'a.b.c' (namespace)>
      
    2. The from ... import ... statement remembers only the imported name.
      This name must not be qualified:

      In[1]: from a.b import c
      
      In[2]: a
      NameError: name 'a' is not defined
      
      In[2]: a.b
      NameError: name 'a' is not defined
      
      In[3]: a.b.c
      NameError: name 'a' is not defined
      
      In[4]: c
      Out[4]: <module 'a.b.c' (namespace)>
      

    • Note: Of course, I restarted my Python console between steps 1 and 2.
    0 讨论(0)
  • 2020-11-21 08:17

    One of the significant difference I found out which surprisingly no-one has talked about is that using plain import you can access private variable and private functions from the imported module, which isn't possible with from-import statement.

    Code in image:

    setting.py

    public_variable = 42
    _private_variable = 141
    def public_function():
        print("I'm a public function! yay!")
    def _private_function():
        print("Ain't nobody accessing me from another module...usually")
    

    plain_importer.py

    import settings
    print (settings._private_variable)
    print (settings.public_variable)
    settings.public_function()
    settings._private_function()
    
    # Prints:
    # 141
    # 42
    # I'm a public function! yay!
    # Ain't nobody accessing me from another module...usually
    

    from_importer.py

    from settings import *
    #print (_private_variable) #doesn't work
    print (public_variable)
    public_function()
    #_private_function()   #doesn't work
    
    0 讨论(0)
提交回复
热议问题