Python 매뉴얼 모듈

巴扎黑
풀어 주다: 2017-06-23 16:29:36
원래의
1418명이 탐색했습니다.

[번역]The Python Tutorial#Modules

6. Modules

Python 인터프리터를 종료했다가 다시 시작하면 이전에 정의한 이름(함수 및 변수)이 손실됩니다. 따라서 더 긴 프로그램을 작성하려면 대신 파일을 입력으로 사용하여 텍스트 편집기를 사용하여 인터프리터에 대한 입력을 준비하는 것이 좋습니다. 이를 스크립트 생성이라고도 합니다. 프로그램이 길어지면 유지 관리가 쉽도록 프로그램을 여러 파일로 나눌 수 있습니다. 또한 해당 정의를 각 프로그램에 복사하지 않고 여러 프로그램에서 유용한 기능을 사용할 수도 있습니다.

이러한 요구를 지원하기 위해 Python은 정의를 파일에 넣고 이를 스크립트나 인터프리터의 대화형 인스턴스에서 사용하는 방법을 제공합니다. 이러한 파일을 모듈이라고 합니다. 모듈의 정의는 다른 모듈이나 기본 모듈(최상위 스크립트 및 계산 모드에서 액세스할 수 있는 변수 세트)로 가져올 수 있습니다.

모듈은 Python 정의와 명령문이 포함된 파일입니다. 파일 이름은 모듈 이름이며 접미사 .py가 있습니다. 모듈 내에서 모듈 이름(문자열)은 전역 변수 __name__의 값으로 사용할 수 있습니다. 예를 들어, 즐겨 사용하는 텍스트 편집기를 사용하여 현재 디렉터리에 다음 내용이 포함된 fibo.py 파일을 만듭니다. .py后缀。在模块中,模块的名字(作为字符串),作为全局变量__name__的值,是可用的。例如,使用你最喜欢的文本编辑器在当前目录创建fibo.py文件,内容如下:

# Fibonacci numbers moduledef fib(n):    # write Fibonacci series up to na, b = 0, 1while b < n:print(b, end=&#39; &#39;)
        a, b = b, a+bprint()def fib2(n):   # return Fibonacci series up to nresult = []
    a, b = 0, 1while b < n:
        result.append(b)
        a, b = b, a+breturn result
로그인 후 복사

进入Python解释器,使用下列命令导入这个模块:

>>> import fibo
로그인 후 복사

这个操作并不会讲fibo中定义的函数的名字导入到当前符号表中;只是导入模块的名字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__&#39;fibo&#39;
로그인 후 복사

如果想要频繁使用函数,可以将其赋值给局部名字:

>>> fib = fibo.fib>>> fib(500)1 1 2 3 5 8 13 21 34 55 89 144 233 377
로그인 후 복사

6.1 More on Modules

模块可以同时包含可执行语句和函数定义。可执行语句用来初始化模块。当模块名字出现在导入语句中时,这些可执行语句只执行一次[1]。(如果文件作为脚本,这些可执行也会执行)

每一个模块都有自己私有的符号表,这个符号表被所有定义在模块中的函数作为全局符号表使用。因此,模块的作者可以使用这些全局变量,而不用担心和用于全局变量偶然的名字冲突。另一方面,如果你知道自己在做什么,你可以使用与引用函数相同的方法来引用模块的全局变量,modname.itemname

模块可以引用其他模块。将所有import语句放置到模块的开始处(或者脚本)是一个很好的习惯,但并不是强制的。被导入的模块名字将会被放置到当前模块的全局符号表中。

有一种导入语句的变种方法,将模块的名字直接导入到当前模块的符号表中。例如:

>>> from fibo import fib, fib2>>> fib(500)1 1 2 3 5 8 13 21 34 55 89 144 233 377
로그인 후 복사

以上并不会引入模块的名字(在上面的例子中fibo不会被定义)。

甚至有一种方法可以导入模块中定义的所有名字:

>>> from fibo import *>>> fib(500)1 1 2 3 5 8 13 21 34 55 89 144 233 377
로그인 후 복사

这种方法导入所有不以下划线_开头的名字。大多数情况下,Python程序员不会使用这种方法,因为这会导入未知的名字集合到解释器中,也许还会屏蔽已经定义的一些名字。

需要注意,通常在实践中从模块或者包中导入所以名字是不鼓励使用的,因为会降低程序的易读性。然而,在交互式环境中使用它来减少打字输入是可行的。

注意: 出于性能原因,一个解释器会话中每个模块只导入一次。因此,如果模块被改变了,必须重启解释器;如果只想要交互式测试一个模块,使用 importlib.reload(),例如:import importlib; importlin.reload(modulename)

6.1.1 Executing modules as scripts

当使用以下命令运行Python模块:

python fibo.py <arguments>
로그인 후 복사

模块中的代码会被执行,就像导入该模块一样,但是这时__name__被设置为__main__。这意味着以下代码会加入到模块末尾:

if __name__ == "__main__":import sys
    fib(int(sys.argv[1]))
로그인 후 복사

模块即作为脚本执行,也可以作为模块导入,因为只有当模块作为mian

$ python fibo.py 501 1 2 3 5 8 13 21 34
로그인 후 복사
Python 인터프리터를 입력하고 다음 명령을 사용하여 이 모듈을 가져옵니다.

>>> import fibo>>>
로그인 후 복사
이 작업은 fibo에 정의된 함수의 이름을 현재 기호 테이블로 가져오지 않고, fibo 모듈의 이름만 가져옵니다. 모듈 이름을 사용하여 함수에 액세스할 수 있습니다. 🎜🎜
>>> import sys>>> sys.ps1&#39;>>> &#39;>>> sys.ps2&#39;... &#39;>>> sys.ps1 = &#39;C> &#39;C> print(&#39;Yuck!&#39;)
Yuck!C>
로그인 후 복사
로그인 후 복사
🎜🎜함수를 자주 사용하려면 함수를 로컬 이름에 할당할 수 있습니다. 🎜🎜
>>> import sys>>> sys.path.append(&#39;/ufs/guido/lib/python&#39;)
로그인 후 복사
로그인 후 복사
🎜

6.1 모듈에 대한 추가 정보

🎜모듈에는 실행 파일도 포함될 수 있습니다. 명령문 및 함수 정의. 실행 가능한 문은 모듈을 초기화하는 데 사용됩니다. import 문에 모듈 이름이 나타나면 이러한 실행 가능 문은 [1] 한 번만 실행됩니다. (파일이 스크립트로 사용되는 경우 이러한 실행 파일도 실행됩니다)🎜🎜각 모듈에는 모듈에 정의된 모든 함수에서 전역 기호 테이블로 사용되는 자체 전용 기호 테이블이 있습니다. 따라서 모듈 작성자는 전역 변수에 사용된 이름과 실수로 이름이 충돌하는 것을 걱정하지 않고 이러한 전역 변수를 사용할 수 있습니다. 반면, 수행 중인 작업을 알고 있다면 modname.itemname 함수를 참조하는 것과 같은 방식으로 모듈의 전역 변수를 참조할 수 있습니다. 🎜🎜모듈은 다른 모듈을 참조할 수 있습니다. 모듈(또는 스크립트) 시작 부분에 모든 import 문을 배치하는 것이 좋지만 필수는 아닙니다. 가져온 모듈 이름은 현재 모듈의 전역 기호 테이블에 배치됩니다. 🎜🎜모듈 이름을 현재 모듈의 기호 테이블로 직접 가져오는 import 문의 변형이 있습니다. 예: 🎜🎜
>>> import fibo, sys>>> dir(fibo)
['__name__', 'fib', 'fib2']>>> dir(sys)  
['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__', '__package__', '__stderr__', '__stdin__', '__stdout__', '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe', '_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv', 'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info', 'float_repr_style', 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags', 'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount', 'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info', 'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1', 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout', 'thread_info', 'version', 'version_info', 'warnoptions']
로그인 후 복사
로그인 후 복사
🎜🎜위에서는 모듈 이름을 소개하지 않습니다(위 예에서는 fibo가 정의되지 않음). 🎜🎜모듈에 정의된 모든 이름을 가져오는 방법도 있습니다. 🎜🎜
>>> a = [1, 2, 3, 4, 5]>>> import fibo>>> fib = fibo.fib>>> dir()
['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']
로그인 후 복사
로그인 후 복사
🎜🎜이 방법은 밑줄 _로 시작하지 않는 모든 이름을 가져옵니다. 대부분의 경우 Python 프로그래머는 이 방법을 사용하지 않습니다. 왜냐하면 알 수 없는 이름 세트를 인터프리터로 가져오고 이미 정의된 일부 이름을 차단할 수도 있기 때문입니다. 🎜🎜실제로 모듈이나 패키지에서 가져오는 것은 프로그램의 가독성을 떨어뜨리므로 일반적으로 권장되지 않습니다. 그러나 입력을 줄이기 위해 대화형 환경에서 사용할 수 있습니다. 🎜
🎜참고: 성능상의 이유로 각 모듈은 통역사 세션당 한 번만 가져옵니다. 따라서 모듈이 변경되면 인터프리터를 다시 시작해야 합니다. 모듈을 대화형으로만 테스트하려면 importlib.reload()를 사용하세요. 예: import importlib.reload; (modulename )🎜
6.1.1 스크립트로 모듈 실행
🎜다음 명령을 사용하여 Python 모듈을 실행할 때: 🎜🎜
>>> import builtins>>> dir(builtins)  
[&#39;ArithmeticError&#39;, &#39;AssertionError&#39;, &#39;AttributeError&#39;, &#39;BaseException&#39;, &#39;BlockingIOError&#39;, &#39;BrokenPipeError&#39;, &#39;BufferError&#39;, &#39;BytesWarning&#39;, &#39;ChildProcessError&#39;, &#39;ConnectionAbortedError&#39;, &#39;ConnectionError&#39;, &#39;ConnectionRefusedError&#39;, &#39;ConnectionResetError&#39;, &#39;DeprecationWarning&#39;, &#39;EOFError&#39;, &#39;Ellipsis&#39;, &#39;EnvironmentError&#39;, &#39;Exception&#39;, &#39;False&#39;, &#39;FileExistsError&#39;, &#39;FileNotFoundError&#39;, &#39;FloatingPointError&#39;, &#39;FutureWarning&#39;, &#39;GeneratorExit&#39;, &#39;IOError&#39;, &#39;ImportError&#39;, &#39;ImportWarning&#39;, &#39;IndentationError&#39;, &#39;IndexError&#39;, &#39;InterruptedError&#39;, &#39;IsADirectoryError&#39;, &#39;KeyError&#39;, &#39;KeyboardInterrupt&#39;, &#39;LookupError&#39;, &#39;MemoryError&#39;, &#39;NameError&#39;, &#39;None&#39;, &#39;NotADirectoryError&#39;, &#39;NotImplemented&#39;, &#39;NotImplementedError&#39;, &#39;OSError&#39;, &#39;OverflowError&#39;, &#39;PendingDeprecationWarning&#39;, &#39;PermissionError&#39;, &#39;ProcessLookupError&#39;, &#39;ReferenceError&#39;, &#39;ResourceWarning&#39;, &#39;RuntimeError&#39;, &#39;RuntimeWarning&#39;, &#39;StopIteration&#39;, &#39;SyntaxError&#39;, &#39;SyntaxWarning&#39;, &#39;SystemError&#39;, &#39;SystemExit&#39;, &#39;TabError&#39;, &#39;TimeoutError&#39;, &#39;True&#39;, &#39;TypeError&#39;, &#39;UnboundLocalError&#39;, &#39;UnicodeDecodeError&#39;, &#39;UnicodeEncodeError&#39;, &#39;UnicodeError&#39;, &#39;UnicodeTranslateError&#39;, &#39;UnicodeWarning&#39;, &#39;UserWarning&#39;, &#39;ValueError&#39;, &#39;Warning&#39;, &#39;ZeroDivisionError&#39;, &#39;_&#39;, &#39;__build_class__&#39;, &#39;__debug__&#39;, &#39;__doc__&#39;, &#39;__import__&#39;, &#39;__name__&#39;, &#39;__package__&#39;, &#39;abs&#39;, &#39;all&#39;, &#39;any&#39;, &#39;ascii&#39;, &#39;bin&#39;, &#39;bool&#39;, &#39;bytearray&#39;, &#39;bytes&#39;, &#39;callable&#39;, &#39;chr&#39;, &#39;classmethod&#39;, &#39;compile&#39;, &#39;complex&#39;, &#39;copyright&#39;, &#39;credits&#39;, &#39;delattr&#39;, &#39;dict&#39;, &#39;dir&#39;, &#39;divmod&#39;, &#39;enumerate&#39;, &#39;eval&#39;, &#39;exec&#39;, &#39;exit&#39;, &#39;filter&#39;, &#39;float&#39;, &#39;format&#39;, &#39;frozenset&#39;, &#39;getattr&#39;, &#39;globals&#39;, &#39;hasattr&#39;, &#39;hash&#39;, &#39;help&#39;, &#39;hex&#39;, &#39;id&#39;, &#39;input&#39;, &#39;int&#39;, &#39;isinstance&#39;, &#39;issubclass&#39;, &#39;iter&#39;, &#39;len&#39;, &#39;license&#39;, &#39;list&#39;, &#39;locals&#39;, &#39;map&#39;, &#39;max&#39;, &#39;memoryview&#39;, &#39;min&#39;, &#39;next&#39;, &#39;object&#39;, &#39;oct&#39;, &#39;open&#39;, &#39;ord&#39;, &#39;pow&#39;, &#39;print&#39;, &#39;property&#39;, &#39;quit&#39;, &#39;range&#39;, &#39;repr&#39;, &#39;reversed&#39;, &#39;round&#39;, &#39;set&#39;, &#39;setattr&#39;, &#39;slice&#39;, &#39;sorted&#39;, &#39;staticmethod&#39;, &#39;str&#39;, &#39;sum&#39;, &#39;super&#39;, &#39;tuple&#39;, &#39;type&#39;, &#39;vars&#39;, &#39;zip&#39;]
로그인 후 복사
로그인 후 복사
🎜🎜모듈의 코드가 실행됩니다. , 가져오기와 마찬가지로 모듈은 동일하지만 이제 __name____main__으로 설정됩니다. 이는 다음 코드가 모듈 끝에 추가된다는 것을 의미합니다: 🎜🎜
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
              ...
로그인 후 복사
로그인 후 복사
🎜🎜모듈은 스크립트로 실행되며 모듈이 mian으로 실행될 때만 모듈로 가져올 수도 있습니다. 파일에서 명령줄 코드가 구문 분석됩니다. 실행됩니다: 🎜🎜
import sound.effects.echo
로그인 후 복사
로그인 후 복사
🎜🎜모듈을 가져오면 코드가 실행되지 않습니다: 🎜🎜
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
로그인 후 복사
로그인 후 복사
🎜

这可以用来为使用者提供一个模块用户接口的使用约定,也可以用作测试(模块作为脚本时执行测试用例)

6.1.2 The Module Search Path

当模块spam被导入时,解释器首先搜索built-in模块。如果没有找到,解释器在变量sys.path提供的路径列表中搜索名为spam.py的文件。sys.path从下列位置初始化:

  • 包含输入脚本的目录(或者没有指定文件时的当前目录)

  • PYTHONPATH(目录名字集合,与shell环境变量PATH相似,也是环境变量)

  • 安装默认目录

注意: 在支持符号链接的文件系统,包含输入脚本的目录是符号链接指向的目录。也就是说包含符号链接的目录不会被加入到搜索路径中。

初始化后,Python程序可以修改sys.path。包含执行脚本的目录被放置到搜索路径的开始,在标准库路径之前。这意味着该目录中的脚本会被加载,而标准库目录中的同名模块不会被加载。这会引发错误,除非是有意替换标准库的模块。阅读Standard Modules获取更多信息。 (译注:自定义的模块不应与标准模块重名,否则标准模块会被覆盖。)

6.1.3 “Compiled” Python files

为加速模块加载,Python会在__pycache__目录中缓存每个模块的编译版本,缓存文件名为module.version.pycversion编码了被编译文件的版本;通常包含了Python的版本号。例如,在CPython release 3.3中,文件spam.py的编译版本会被缓存为__pycache__/spam.cpython-33.pyc。这种命名约定允许来自不同Python发行版本的模块得以共存。

Python检查源文件的修改日期与编译版本,来确定编译版本是否过期,是否需要重新编译。这是一个完全自动化的过程。另外,编译模块是平台独立的,因此异构系统可以共享相同的库。

Python不会检查在两个环境中的缓存。首先,Python总是重新编译,并且不会存储直接从命令行加载的模块的结果。其次,如果没有源模块,Python不检查缓存。若要支持无源文件(只有编译版本)分布,那么编译的模块必须放在源文件目录中,并且源模块必需不存在。

给专家的建议:

  • 可以在命令行使用-O或者-OO开关来减少编译模块的大小。-O参数移除assert语句,-OO参数同时移除assert语句和__doc__字符串。由于一些程序依赖这些变量,那么只有当你确认你要这么做时,才能使用这两个参数。“优化的”模块有一个opt-标签并且通常更小。未来的发型版本可能改变优化的影响。

  • .pyc文件中读取的程序不会比从.py文件读取的程序跑得快;.pyc文件快的地方在于加载。

  • compileall模块可以为目录中的所有模块创建.pyc文件。

  • PEP 3147中有关系这点的更多信息,包括一个决策流程

6.2 Standard Modules

Python提供了标准模块库,在独立文档中描述,名为Python Library Reference(以后叫做Library Reference)。有一些模块内嵌入解释器中,这些模块不是语言核心的一部分,但是它们是内嵌的,这既是为性能考虑,也提供了访问如系统调用般的操作系统原生接口的方式。这些模块集合依赖底层平台的配置选项。例如winreg模块只在Windows系统中提供。一个特殊的模块值得注意:sys,这个模块内嵌在所有Python解释器中。变量sys.ps1sys.ps2定义了主提示符和辅助提示符的字符串:

>>> import sys>>> sys.ps1&#39;>>> &#39;>>> sys.ps2&#39;... &#39;>>> sys.ps1 = &#39;C> &#39;C> print(&#39;Yuck!&#39;)
Yuck!C>
로그인 후 복사
로그인 후 복사

只有当解释器以交互模式运行才会定义这两个变量。

变量sys.path是决定解释器模块搜索路径的字符列表。该变量从环境变量PYTHONPATH,或者内置默认路径(PYTHONPATH未指定时)初始化。可以使用标准list操作修改它的值:

>>> import sys>>> sys.path.append(&#39;/ufs/guido/lib/python&#39;)
로그인 후 복사
로그인 후 복사

6.3 The dir() Function

内嵌函数dir()用于搜索模块定义的名字。返回一个有序字符串列表:

>>> import fibo, sys>>> dir(fibo)
['__name__', 'fib', 'fib2']>>> dir(sys)  
['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__', '__package__', '__stderr__', '__stdin__', '__stdout__', '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe', '_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv', 'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info', 'float_repr_style', 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags', 'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount', 'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info', 'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1', 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout', 'thread_info', 'version', 'version_info', 'warnoptions']
로그인 후 복사
로그인 후 복사

不带参数使用dir()函数,会列出当前作用域的全部名字:

>>> a = [1, 2, 3, 4, 5]>>> import fibo>>> fib = fibo.fib>>> dir()
['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']
로그인 후 복사
로그인 후 복사

需要注意该函数列出所有类型的名字:变量,模块,函数,等等。

dir()不会列出内嵌函数和变量的名字。如果希望列出,这些名字定义在标准模块builtins中:

>>> import builtins>>> dir(builtins)  
[&#39;ArithmeticError&#39;, &#39;AssertionError&#39;, &#39;AttributeError&#39;, &#39;BaseException&#39;, &#39;BlockingIOError&#39;, &#39;BrokenPipeError&#39;, &#39;BufferError&#39;, &#39;BytesWarning&#39;, &#39;ChildProcessError&#39;, &#39;ConnectionAbortedError&#39;, &#39;ConnectionError&#39;, &#39;ConnectionRefusedError&#39;, &#39;ConnectionResetError&#39;, &#39;DeprecationWarning&#39;, &#39;EOFError&#39;, &#39;Ellipsis&#39;, &#39;EnvironmentError&#39;, &#39;Exception&#39;, &#39;False&#39;, &#39;FileExistsError&#39;, &#39;FileNotFoundError&#39;, &#39;FloatingPointError&#39;, &#39;FutureWarning&#39;, &#39;GeneratorExit&#39;, &#39;IOError&#39;, &#39;ImportError&#39;, &#39;ImportWarning&#39;, &#39;IndentationError&#39;, &#39;IndexError&#39;, &#39;InterruptedError&#39;, &#39;IsADirectoryError&#39;, &#39;KeyError&#39;, &#39;KeyboardInterrupt&#39;, &#39;LookupError&#39;, &#39;MemoryError&#39;, &#39;NameError&#39;, &#39;None&#39;, &#39;NotADirectoryError&#39;, &#39;NotImplemented&#39;, &#39;NotImplementedError&#39;, &#39;OSError&#39;, &#39;OverflowError&#39;, &#39;PendingDeprecationWarning&#39;, &#39;PermissionError&#39;, &#39;ProcessLookupError&#39;, &#39;ReferenceError&#39;, &#39;ResourceWarning&#39;, &#39;RuntimeError&#39;, &#39;RuntimeWarning&#39;, &#39;StopIteration&#39;, &#39;SyntaxError&#39;, &#39;SyntaxWarning&#39;, &#39;SystemError&#39;, &#39;SystemExit&#39;, &#39;TabError&#39;, &#39;TimeoutError&#39;, &#39;True&#39;, &#39;TypeError&#39;, &#39;UnboundLocalError&#39;, &#39;UnicodeDecodeError&#39;, &#39;UnicodeEncodeError&#39;, &#39;UnicodeError&#39;, &#39;UnicodeTranslateError&#39;, &#39;UnicodeWarning&#39;, &#39;UserWarning&#39;, &#39;ValueError&#39;, &#39;Warning&#39;, &#39;ZeroDivisionError&#39;, &#39;_&#39;, &#39;__build_class__&#39;, &#39;__debug__&#39;, &#39;__doc__&#39;, &#39;__import__&#39;, &#39;__name__&#39;, &#39;__package__&#39;, &#39;abs&#39;, &#39;all&#39;, &#39;any&#39;, &#39;ascii&#39;, &#39;bin&#39;, &#39;bool&#39;, &#39;bytearray&#39;, &#39;bytes&#39;, &#39;callable&#39;, &#39;chr&#39;, &#39;classmethod&#39;, &#39;compile&#39;, &#39;complex&#39;, &#39;copyright&#39;, &#39;credits&#39;, &#39;delattr&#39;, &#39;dict&#39;, &#39;dir&#39;, &#39;divmod&#39;, &#39;enumerate&#39;, &#39;eval&#39;, &#39;exec&#39;, &#39;exit&#39;, &#39;filter&#39;, &#39;float&#39;, &#39;format&#39;, &#39;frozenset&#39;, &#39;getattr&#39;, &#39;globals&#39;, &#39;hasattr&#39;, &#39;hash&#39;, &#39;help&#39;, &#39;hex&#39;, &#39;id&#39;, &#39;input&#39;, &#39;int&#39;, &#39;isinstance&#39;, &#39;issubclass&#39;, &#39;iter&#39;, &#39;len&#39;, &#39;license&#39;, &#39;list&#39;, &#39;locals&#39;, &#39;map&#39;, &#39;max&#39;, &#39;memoryview&#39;, &#39;min&#39;, &#39;next&#39;, &#39;object&#39;, &#39;oct&#39;, &#39;open&#39;, &#39;ord&#39;, &#39;pow&#39;, &#39;print&#39;, &#39;property&#39;, &#39;quit&#39;, &#39;range&#39;, &#39;repr&#39;, &#39;reversed&#39;, &#39;round&#39;, &#39;set&#39;, &#39;setattr&#39;, &#39;slice&#39;, &#39;sorted&#39;, &#39;staticmethod&#39;, &#39;str&#39;, &#39;sum&#39;, &#39;super&#39;, &#39;tuple&#39;, &#39;type&#39;, &#39;vars&#39;, &#39;zip&#39;]
로그인 후 복사
로그인 후 복사

6.4 Packages

包是使用“圆点模块名”结构化Python模块名字空间的方式。例如,模块名A.B表示包A中的子模块B。就像模块使得不同模块的作者免于担忧每个模块的全局名字一样,圆点模块名的使用使得多模块包(如NumPy或者Python图像库)的作者免于担忧每个模块的名字。

假设需要为统一音频文件和音频数据的处理设计一个模块的集合(包)。有许多不同的音频文件格式(通常通过扩展名辨认,如.wav, .aiff, .au),因此需要为不同文件格式的转换创建和维护一个持续增长的模块集合。也存在许多对音频数据不同的操作(例如混合,增加回声,增加均衡器函数,创建人造立体效果),因此需要额外编写执行这些操作的大量模块。以下是包的可能结构(以层级文件结构来表示):

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
              ...
로그인 후 복사
로그인 후 복사

导入包时,Python搜索sys.path提供的路径寻找包子目录。

为使Python将普通目录看做包,目录中必须包含__init__.py文件。这样做是为了避免普通的目录名(如string)将以后会出现在模块搜索路径中的有效模块无意识的隐藏掉。最简单的情况是,__init__.py可以是一个空文件,但是它也可以包含可执行的初始化包的代码或者设置__all__变量,后面讲述。

包的用户可以从包中导入独立的模块:

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语句首先测试要导入的项是否在包中存在;如果不存在,Python假设这个项是模块并尝试加载它。如果最后寻找失败,ImportError异常抛出。

相对的,使用import item.subitem.subsubitem时,除了最后一项,每一项都必须是包;最后一项可以是模块或者包但是不能是前面的项中定义的类,函数或者变量。

6.4.1 Importing * From a Package

使用from sound.effects import *会发生什么?理想情况下,总是期望在文件系统中找出所有子模块,并全部导入。全部导入会耗费很长时间,并且导入子模块可能会有不期待的副作用,这些副作用应该在显式导入时发生。

唯一的解决方案是包作者提供一个包的显式索引。import语句遵循以下约定:如果包的__init__.py代码中定义了名为__all__的变量,那么使用from package import *时会导入该变量指定的所有模块。当包的新版本发布时,由包作者负责更新列表__all__。如果包作者不希望可以使用from package import *导入包中的模块,也可以不支持__all__。 例如,文件sound/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.echoimport sound.effects.surroundfrom sound.effects import *
로그인 후 복사

这个例子中,echosurround模块被导入到当前名字空间中,因为执行from... import时,它们已经定义在sound.effects包中定义了。(定义了__all__时同样有效)

尽管使用import *时只有符合特定模式的名字会被导出,但仍然不建议在生产代码中使用。

记住,使用form Package import specific_submodle没有错误。实际上,这是推荐的方法,除非当前模块需要使用其他包中的同名模块。

6.4.2 Intra-package References

当包中包含了子包结构(就如例子中的sound包),可以使用绝对导入的方式引用兄弟包中的子模块。例如,如果模块sound.filters.vocoder需要使用包sound.effects中的echo模块,可以使用from sound.effects import echo

也可以使用from modul import name语句来相对导入模块。这种方式使用点.指示当前包和相对导入中涉及的父包。以surround模块为例:

from . import echofrom .. import formatsfrom ..filters import equalizer
로그인 후 복사

相对导入基于当前模块的名字。由于主模块的名字总是__main__,要当做Python应用主模块使用的模块必须总是使用绝对导入的方式。

6.4.3 Packages in Multiple Directories

包还支持一个特殊属性,__path__。在__init__.py中的代码执行之前,属性__path__被初始化为一个列表,这个列表包含了持有该__init__.py文件的目录的路径。该变量可修改,这样做会影响将来的对包内模块和子包的搜索。

然而这个特性不总是需要的,它可以用来扩展包的模块集合

Footnotes

[1] 实际上,函数定义也是可“执行”的“语句”;模块级别的函数执行将函数的名字放置到模块的全局符号表中

위 내용은 Python 매뉴얼 모듈의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!