Research on the mechanism of using statements to import modules or packages in Python _python

Source: Internet
Author: User
Tags in python

This article discusses Python's from <module> import * and from <package> import *, how they are executed, and why it is a bad idea to use this syntax (perhaps).
import all from one module

From <module> Import * means means "I want to have access to all the names I have permission to access in <module>." For example, the following code something.py:

# something.py
 
public_variable =
_private_variable =
 
public_function ():
  print ("I ' m a public function! yay! ")
 
Def _private_function ():
  print ("Ain ' t nobody accessing me from another module...usually")
 
class Publicclass ( Object):
  Pass
 
class _weirdclass (object):
  Pass

In the Python interpreter, we can perform the from something import * and see the following:

>>> from something import *
>>> public_variable
>>> _private_variable
...
Nameerror:name ' _private_variable ' isn't defined
>>> public_function ()
"I ' m a public function! yay!"
>>> _private_function () ...
Nameerror:name ' _private_function ' is not defined
>>> c = publicclass ()
>>> C
< Something. Publicclass object at ...>
>>> C = _weirdclass () ...
Nameerror:name ' _weirdclass ' is not defined

From something import * imported from something all names other than the name of _ beginning with _, the name started by the specification is private so it has not been imported.
Well, not particularly bad! What else?

There's no mention of what __all__ is. __ALL__ is a list of strings that specifies which symbols in the module (or the package mentioned later) will be exported when the from <module> import * is used. If we do not define __ALL__ (which we do not define on the something.py above), import * The default way of importing is to import all names except the beginning of the underscore (_). Again, the programming Convention underlines that a symbol is private and not imported is reasonable. Let's take a look at what happens when we define our own __all__ in something.py.

# something.py
 
__all__ = [' _private_variable ', ' Publicclass ']
 
# The rest is the same as before
 
Public_variabl E =
_private_variable =
 
public_function def ():
  print ("I ' m a public function! yay! ")
 
Def _private_function ():
  print ("Ain ' t nobody accessing me from another module...usually")
 
class Publicclass ( Object):
  Pass
 
class _weirdclass (object):
  Pass

Now, we expect the from something import * to only be imported into _private_variable and Publicclass:

>>> from something import *
>>> public_variable
>>> _private_variable
...
Nameerror:name ' _private_variable ' isn't defined
>>> public_function ()
"I ' m a public function! yay!"
>>> _private_function () ...
Nameerror:name ' _private_function ' is not defined
>>> c = publicclass ()
>>> C
< Something. Publicclass object at ...>
>>> C = _weirdclass () ...
Nameerror:name ' _weirdclass ' is not defined

What's the bag like?

When you import all from a package, the __all__ approach is essentially the same as the module, but it handles the modules in the package (rather than importing the names in the module). So when we use the From <package> import *. __all__ describes all the modules that need to be imported into the current namespace.

The difference is that if you don't declare a __all__,from <package> import * statement in a package that doesn't import anything (this is not entirely true, the correct argument is __init__.py)
but what's wrong with that?

Before you continue reading, in your Python interpreter, perform import this, and then read the Python Zen (read to them before your child sleeps every night).

Clarity is better than ambiguity.

From <module> Import * is ambiguous. It doesn't tell us what we're importing or what we're bringing into the current namespace. A better approach is to explicitly import all the names we need. In this way, the reader (most likely the future yourself) will not be confused with a variable/method/class/category used in your code, which also tells us the next point:

Readability is important

Even if you need to import a lot of things, an explicit import is clearer. Use pep 328:

From Tkinter import (Tk, Frame, Button, Entry, Canvas, Text, left
  , DISABLED, NORMAL, RIDGE, end)

You can now know exactly what is in your namespace, and using Ctrl+f can quickly tell you where they came from.

At the same time, you always have to bear the risk of the module/package author changing the list content (plus/minus things). Which is either of the following:

The author removed a string from the __all__. If your code uses that name, your code will report a nameerror error, and it's hard to see why.
The author added a lot of things to the __all__. You may not need these additions, so you're just letting those things that you don't care about fill up your namespaces. They even replace other content of the same name when you're not looking.

Of course, sometimes it's useful to import everything from a module or a package. However, think twice before doing so. From my experience, it's usually just laziness.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.