6.Modules
def fib (n) :
a, b = 0 , 1
while b < n:
print(b, end=' ' )
a, b = b, a+b
print()
def fib2 (n) :
result = []
a, b = 0 , 1
while b < n:
result.append(b)
a, b = b, a+b
return result
>>> import fibo
>>> fibo.fib(1000 )
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100 )
[1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , 34 , 55 , 89 ]
>>> fibo.__name__
'fibo'
>>>
>>> fib = fibo.fib
>>> fib(500 )
1 1 2 3 5 8 13 21 34 55 89 144 233 377
More on Modules 深入模块
>>> from fibo import fib, fib2
>>> fib(500 )
1 1 2 3 5 8 13 21 34 55 89 144 233 377
>>> from fibo import *
>>> fib(500 )
1 1 2 3 5 8 13 21 34 55 89 144 233 377
dir() 函数
>>>
>>> import fibo, sys
>>> dir(fibo)
['__name__' , 'fib' , 'fib2' ]
>>> dir(sys)
['__displayhook__' , '__doc__' , '__excepthook__' , '__name__' , '__stderr__' ,
'__stdin__' , '__stdout__' , '_getframe' , 'api_version' , 'argv' ,
'builtin_module_names' , 'byteorder' , 'callstats' , 'copyright' ,
'displayhook' , 'exc_info' , 'excepthook' ,
'exec_prefix' , 'executable' , 'exit' , 'getdefaultencoding' , 'getdlopenflags' ,
'getrecursionlimit' , 'getrefcount' , 'hexversion' , 'maxint' , 'maxunicode' ,
'meta_path' , 'modules' , 'path' , 'path_hooks' , 'path_importer_cache' ,
'platform' , 'prefix' , 'ps1' , 'ps2' , 'setcheckinterval' , 'setdlopenflags' ,
'setprofile' , 'setrecursionlimit' , 'settrace' , 'stderr' , 'stdin' , 'stdout' ,
'version' , 'version_info' , 'warnoptions' ]
>>>
>>> a = [1 , 2 , 3 , 4 , 5 ]
>>> import fibo
>>> fib = fibo.fib
>>> dir()
['__builtins__' , '__doc__' , '__file__' , '__name__' , 'a' , 'fib' , 'fibo' , 'sys' ]
Packages 包
sound/ Top-level package
__init__.py Initialize the sound package
formats/ Subpackage for file format conversions
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ Subpackage for sound effects
__init__.py
echo.py
surround.py
reverse.py
...
filters/ Subpackage for filters
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
用户可以每次只导入包里的特定模块,例如:
import sound.effects.echo
这样就导入了 sound.effects.echo 子模块。它必需通过完整的名称来引用。
sound.effects.echo.echofilter(input, output, delay=0.7 , atten=4 )
导入包时有一个可以选择的方式:
from sound.effects import echo
这样就加载了 echo 子模块,并且使得它在没有包前缀的情况下也可以使用,所以它可以如下方式调用
echo.echofilter(input, output, delay=0.7 , atten=4 )
还有另一种变体用于直接导入函数或变量:
from sound.effects.echo import echofilter
这样就又一次加载了 echo 子模块,但这样就可以直接调用它的 echofilter() 函数:
echofilter(input, output, delay=0.7 , atten=4 )
需要注意的是使用 from package import item 方式导入包时,这个子项(item)既可以是包中的一个子模块(或一个子包),也可以是包中定义的其它命名,像函数、类或变量。import 语句首先核对是否包中有这个子项,如果没有,它假定这是一个模块,并尝试加载它。如果没有找到它,会引发一个 ImportError 异常。相反,使用类似 import item.subitem.subsubitem 这样的语法时,这些子项必须是包,最后的子项可以是包或模块,但不能是前面子项中定义的类、函数或变量。
Importing * From a Package 从 * 导入包
那么当用户写下 from sound.Effects import * 时会发生什么事?理想中,总是希望在文件系统中找出包中所有的子模块,然后导入它们。这可能会花掉委有长时间,并且出现期待之外的边界效应,导出了希望只能显式导入的包。
对于包的作者来说唯一的解决方案就是给提供一个明确的包索引。 import 语句按如下条件进行转换:执行 from package import * 时,如果包中的 __init__.py 代码定义了一个名为 __all__ 的列表,就会按照列表中给出的模块名进行导入。新版本的包发布时作者可以任意更新这个列表。如果包作者不想 import * 的时候导入他们的包中所有模块,那么也可能会决定不支持它( import * )。例如, sounds/effects/__init__.py 这个文件可能包括如下代码:
__all__ = ["echo" , "surround" , "reverse" ]
这意味着 from Sound.Effects import * 语句会从 sound 包中导入以上三个已命名的子模块。
如果没有定义 __all__ , from Sound.Effects import * 语句 不会 从 sound.effects 包中导入所有的子模块。无论包中定义多少命名,只能确定的是导入了 sound.effects 包(可能会运行 __init__.py 中的初始化代码)以及包中定义的所有命名会随之导入。这样就从 __init__.py 中导入了每一个命名(以及明确导入的子模块)。同样也包括了前述的 import 语句从包中明确导入的子模块,考虑以下代码:
import sound.effects.echo
import sound.effects.surround
from sound.effects import *
在这个例子中, echo 和 surround 模块导入了当前的命名空间,这是因为执行 from ...import 语句时它们已经定义在 sound.effects 包中了(定义了 __all__ 时也会同样工作)。
Intra-package References 包内引用
如果包中使用了子包结构(就像示例中的 sound 包),可以按绝对位置从相邻的包中引入子模块。例如,如果 sound.filters.vocoder 包需要使用 sound.effects 包中的 echo 模块,它可以 from Sound.Effects import echo 。
你可以用这样的形式 from module import name 来写显式的相对位置导入。那些显式相对导入用点号标明关联导入当前和上级包。以 surround 模块为例,你可以这样用:
from . import echo
from .. import formats
from ..filters import equalizer
需要注意的是显式或隐式相对位置导入都基于当前模块的命名。因为主模块的名字总是 "__main__" ,Python 应用程序的主模块应该总是用绝对导入。