1. 模块 (Modules)
将定义的内容放在文件中 ,然后在脚本或者交互模式中使用 。这里的文件就叫做 模块(module). 一个模块 可以导入到其他的模块中 。模块是包含 Python 定义和声明的文件。文件名 是由 模块名 加上.py 后缀 组成 。 模块名(作为一个字符串) 可以通过全局变量 __name__ 获得 。
i.e: fibo.py 文件
def fib(n):
a,b = 0,1
result = []
while a < n:
result.append(a)
a,b = b,a+b
return result
在包含该文件的目录下,打开cmd ,进入交互模式,导入fibo.py 模块 ,即可调用 fib(n) 函数。
$ python
Python 3.4.2 (v3.4.2:ab2c023a9432, Oct 6 2014, 22:15:05) [MSC v.1600 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import fibo
>>> fibo.fib(100)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fib = fibo.fib
>>> fib(200)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]
>>>
>>> import fibo
>>> fibo.__name__
'fibo'
>>>
1.1 更多关于 module
模块包含 可执行语句 以及 已定义的函数 。 可执行语句通常用于初始化模块 ,只在第一次导入时执行(如果文件以脚本方式执行,这些语句也会执行)。
每个模块都有自己私有的符号表 。
模块中可以导入其他模块。导入方式 :
导入指定的函数名
>>> from fibo import fib
>>> fib(100)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>>
或者导入所有 (不建议此种方法导入)
>>> from fibo import *
>>> fib(200)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]
>>>
1.1.1 将模块作为脚本执行,不使用交互模式
Python <module>.py <arguments>
例如 ,调用 fibo.py 模块
python fibo.py 20
通过执行脚本的方式 ,此时
__name__ 的 值 为 __main__
而通过交互模式执行 的 __name__ 的值为 fibo
调用后并不会执行函数,此时可以在 模块的末尾 加上如下的判断,然后执行 fib(n) 函数 :
if __name__ == '__main__':
import sys
fib(int(sys.argv[1]))
通过该方法 , 可以保证该文件既可以作为脚本执行 (用于测试),也可以导入模块使用 。
1.1.2 模块搜索路径
当模块 spam 被导入时,解释器首先在内置模块中搜索这个名字,如果没有找到,会在 sys.path 指定的一系列目录下 查找 spam.py 这个文件,sys.path 会在这些地方初始化:
★ 脚本的所在目录(如果没指明,则为当前目录)
★ PYTHONPATH (一系列目录名,和系统变量PATH格式一样)
★ 安装时默认的设定
1.1.3 "编译的" Python 文件
为了提高 加载模块的 速度 , Python 在 __pycache__ 目录中缓存每个模块的编译版本 。
以下两种情况不缓存:
★ 直接从命令行加载
★ 如果没有源模块不会检查缓存
1.2 标准模块
Python 自带了标准的模块 。
>>> import sys #sys 模块,它可以修改交互模式下的提示符,修改搜索路径,等等
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = '>>'
>>
只有在交互式模式中,这两个变量才有定义。
>>> import sys
>>> sys.path.append('/ufs/guido/lib/python')
1.3 dir() 函数 : 用来查找 module 定义了 哪些名称 (此处名称的类型包括:变量名,模块名,函数名),并且返回 已排序的字符串的 list
i.e
>>> import fibo,sys
>>> dir(fibo)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'fib', 'fib2', 'sys']
>>> dir(sys)
['__displayhook__', '__doc__', '__egginsert', '__excepthook__', '__interactivehook__', '__loader__', '__name__', '__package__', '__plen', '__spec__', '__stderr__', '__stdin__', '__stdout__', '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe', '_home', '_mercurial', '_xoptions', 'api_version', 'argv', 'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dllhandle', 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info', 'float_repr_style', 'getallocatedblocks', 'getcheckinterval', 'getdefaultencoding', 'getfilesystemencoding', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettrace', 'getwindowsversion', 'hash_info', 'hexversion', 'implementation', 'int_info', 'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout', 'thread_info', 'version', 'version_info', 'warnoptions', 'winver']
>>>
如果不加参数,则列出当前已经定义的名称
i.e
$ py
Python 3.4.2 (v3.4.2:ab2c023a9432, Oct 6 2014, 22:15:05) [MSC v.1600 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
>>> a = [3,4]
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'a']
>>> import fibo
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'fibo']
>>>
但是 dir() 函数不会列出内置的函数和变量 ,可以通过执行 dir(builtins) 查看。
>>> import builtins
>>> dir(builtins)
1.4 包(package)
你的包机构可能是这样的:
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
...
如果你想导入 echo.py 这个模块 ,则可以
①
import sound.effects.echo
该种方法 导入了 echo 模块,如果调用必须使用完整名称来调用:
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
②使用from (推荐使用 from)
from sound.effects import echo
此时调用则可以这样调用
echo.echofilter(input, output, delay=0.7, atten=4)
③导入函数
from sound.effects.echo import echofilter
调用:
echofilter(input, output, delay=0.7, atten=4)
1.4.1 Import * from a packaage
from sound.effects import * : 表面上看是将 effects 模块中的 所有都导入 ,当然这样带来的负面影响就是浪费时间,导入了一些不需要导入的东西。
如果提供显示的索引 :即 声明需要导入的模块名称
在__init__.py 文件中定义 __all__ 的列表 ,那么使用 from package import * 则会根据 __init__中定义的 __all__ 的列表导入。
例如:effects 下 的 _init_.py
__all__ = ["echo", "surround", "reverse"]
执行 from sound.effects import * 将 导入 sound 包下的 三个子模块。
如果 执行 from sound.effects import * ,但是并没有定义 __all__ ,并不会将 sound.effects 下的所有子模块 都导入 ,而是它仅仅确保 sound.effects 包已经导入(也有可能运行了 __init__.py 中的初始化代码)然后导入这个包中定义的任何 名称,这包括了 __init__.py 中定义的名称,同时包括这个包下的任意子模块 中通过 import 显示调用的语句
1.4.3 包内引用
可以使用相对路径导入相邻包内的子模块 ,例如
sound.filters.vocoder.py 模块内需要使用 sound.effects.echo 模块 ,可以使用上面提到的方法 : from sound.effects import echo , 同时也可以使用 相对的方式导入,
一般形式为 : from module import name . 举例如下:(当前在 vocoder 模块中)
from . import karaoke # 同一个子包中的同级模块
from .. import formats # 导入 该模块上级的同级子包
from .. effects import echo #导入相邻子包的子模块