Python的from import *和from import *,它们的作用是引入包来使用,但是它们是如何执行的,为什么要使用这种语法呢?
从一模块导入全部功能
from import * 表示“我想访问我有权访问的所有名称”。例如下面的代码 something.py:
# something.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")
class PublicClass(object):
pass
class _WeirdClass(object):
pass
在 Python 解释器中,我们可以执行 from something import * 并看到如下内容:
>>> from something import *
>>> public_variable
42
>>> _private_variable
...
NameError: name '_private_variable' is not 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 *
从something中导入了除了以_开头名称外的其他所有名称,按照规范,_开始的名称是私有的所以未被导入。
上面没有提到 __all__ 是什么。 __all__ 是一个字符串列表,指定在使用 from import * 时将导出模块(或稍后提到的包)中的哪些符号。如果我们不定义__all__(我们在上面的something.py中没有定义),import *默认的导入方式是导入除了下划线(_)开头的所有名称。同样,编程约定下划线表示符号是私有的,不导入它是合理的。让我们看看当我们在 something.py 中定义我们自己的 __all__ 时会发生什么。
# something.py
__all__ = ['_private_variable', 'PublicClass']
# The rest is the same as before
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")
class PublicClass(object):
pass
class _WeirdClass(object):
pass
现在,我们期望from something import *只会导入_private_variable和PublicClass:
>>> from something import *
>>> public_variable
42
>>> _private_variable
...
NameError: name '_private_variable' is not 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
包是怎样的呢?
从包中导入 all 时, __all__ 的行为方式与模块非常相似,但它处理包中的模块(而不是导入模块中的所有名称)。所以当我们使用 from import *. __all__ 描述了当前命名空间中需要导入的所有模块。
不同的是,如果你不在一个包的__init__.py中声明__all__,那么from import *语句将不会导入任何东西(这个说法并不完全正确,正确的说法在这里)
但是,这有什么不好?
在继续阅读之前,在你的 Python 解释器中,执行 import this,然后再次阅读 Python 之禅(并在每晚睡觉前读给你的孩子听)。
明确比含糊要好。
from import *
是不明确的。它没告诉我们我们正在导入什么或者我们把什么带入当前命名空间了。更好的做法是显式地导入我们需要的全部名称。这种方式下,读者(非常可能是未来的你自己)就不会困惑于你代码中使用的一个变量/方法/类/其他东西是哪儿来的,这也告诉了我们下一点:
可读性很重要
即使你需要导入很多东西,显式地一个一个地导入会更清晰。使用 PEP 328:
from Tkinter import (Tk, Frame, Button, Entry, Canvas, Text,
LEFT, DISABLED, NORMAL, RIDGE, END)
你现在确切地知道你的名称空间中有什么,并且使用 ctrl+f 可以快速告诉你它来自哪里。
此外,你总是冒着模块/包作者更改列表内容(添加/减去内容)的风险。
本文为原创文章,版权归知行编程网所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ Python中的套接字网络通信11/17
- ♥ python函数是否传递数组参数09/23
- ♥ python中input的使用注意事项11/21
- ♥ 什么是 python pep811/17
- ♥ python的归并排序算法流程图详解12/15
- ♥ python通常用来做什么11/29
内容反馈