Python3.7官方向导翻译之python模块

如果你从Python解释器中退出并重新输入,你所做的定义(函数和变量)将会丢失。 因此,如果你想编写一个稍长的程序,最好使用文本编辑器为解释器准备输入,然后用该文件作为输入来运行它。 这被称为创建脚本。 随着程序变长,您可能需要将其分成几个文件以便于维护。 您可能还想使用您在几个程序中编写的方便功能,而不将其定义复制到每个程序中。

为了支持这一点,Python有一种方法可以将定义放在一个文件中,并在脚本或解释器的交互式实例中使用它们。

模块是一个包含Python定义和语句的文件。 文件名是带有后缀.py的模块名称。 在模块中,模块的名称(作为字符串)可用作全局变量name的值。 例如,使用您最喜欢的文本编辑器在当前目录中创建一个名为fibo.py的文件,其中包含以下内容:

# Fibonacci numbers module

def fib(n):
    a, b = 0, 1
    while a < n:
        print(a, end=' ')
        a, b = b, a+b

    print()

def fib2(n):
    result = []
    a, b = 0, 1
    while a < n:
        result.append(a)
        a, b = b, a+b
    return result

现在输入Python解释器并使用以下命令导入此模块:

import fibo

这不会直接在当前符号表中输入在fibo中定义的函数的名称; 它只在那里输入模块名称fibo。 使用模块名称可以访问这些功能:

fibo.fib(1000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 
fibo.fib2(100)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
fibo.__name__
'fibo'

如果您打算经常使用某个功能,则可以将其分配给本地名称local name

fib = fibo.fib
fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 

关于模块的更多信息

一个模块可以包含可执行语句以及函数定义。 这些陈述旨在初始化模块。 它们仅在导入语句中遇到第一次模块名称时执行。 (如果文件作为脚本执行,它们也会运行。)

每个模块拥有自己的私有符号表,这个符号表被模块中定义的所有函数当成全局符号表。因此,模块作者可以使用模块中的全局符号表而不必担心与用户的全局变量发生冲突。另一方面,如果你知道你在做什么,你可以触摸一个模块的全局变量,使用相同的符号来表示它的函数,modname.itemname

模块可以导入其他模块。将所有的import语句放在模块或者脚本的开头是很常见的, 但这不是强制要求的!导入的模块名被放在导入模块的全局符号表中

有一种导入语句的变体(variant),可以将模块中的名称直接导入导入模块的符号表中。
例如:

from fibo import fib, fib2
fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 

这不会在本地符号表中引入进行导入的模块名称(因此在此示例中,未定义fibo)。

甚至有一个变体可以导入模块定义的所有名称

from fibo import *
fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 

这会导入除以下划线(_)开头的所有名称。 在大多数情况下,Python程序员不会使用这个工具,因为它会向解释器中引入一组未知的名称,可能会隐藏您已经定义的一些东西。

请注意,通常从模块或包中导入*的做法是不被接受的,因为它经常会导致代码的可读性差。 但是,可以使用它来保存交互式会话(interactive sessions)中的输入。

如果模块名称后跟as,则后面的名称将直接绑定到导入的模块

import fibo as fib
fib.fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 

这是一种有效的方式,和import fibo做的是一样的,唯一的不同是它可以当作fib使用

它也可以用于从类似的效果中使用:

from fibo import fib as fibonacci
fibonacci(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 

注意出于效率原因,每个模块仅在每个解释器会话中导入一次。 因此,如果更改模块,则必须重新启动解释器 - 或者,如果它只是一个要交互测试的模块,请使用importlib.reload(),例如, import importlib;importlib.reload(模块名)。

把模块当脚本使用

当你用python fibo.py <arguments> 运行Python模块时,模块中的代码会执行,就好像(as if)你导入它一样,但是要将name设置为“main”。 这意味着通过在你的模块的末尾添加这个代码:



import sound.effects.echo
import sound.effects.surround
from sound.effects import *

在这个例子中,echo和surround模块被导入到当前命名空间中,因为它们在执行from … import语句时在sound.effects包中定义。 (当all被定义时,这也是有效的。)

虽然某些模块被设计为只导出使用import *时遵循某些模式的名称,但在生产代码中仍被认为是不好的做法。

请记住,from Package import specific_submodule中使用没有任何问题! 实际上,这是推荐的符号,除非导入模块需要使用不同软件包中具有相同名称的子模块。

内部包参考 Intra-package References

当包被构建为子包时(与示例中的声音包一样),可以使用绝对导入来引用兄弟包的子模块。 例如,如果sound.filters.vocoder模块需要使用sound.effects包中的echo模块,则可以使用from sound.effects import echo。

您还可以使用from module import name的形式来编写相对导入。 这些导入使用前导点(leading dots)来指示相关导入中涉及的当前包和父包。 例如,从surround模块,您可以使用:

from . import echo
from .. import formats
from ..filters import equalizer

请注意,相对导入是基于当前模块的名称。 由于主模块的名称始终为“main”,因此用作Python应用程序主模块的模块必须始终使用绝对导入

多个目录的包

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

虽然此功能通常不是必需的,但它可用于扩展包中的一组模块

阅读更多
个人分类: python
想对作者说点什么? 我来说一句

Python 3.7.0b2 64位安装包

2018年03月08日 25.06MB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭