文档章节

python 中的模块与包

lemos
 lemos
发布于 2017/09/03 08:15
字数 1712
阅读 12
收藏 0

原文

模块

模块就是包含 Python 定义和语句的文件. 文件的名字就是这个模块名再加上 .py. 在一个模块中, 模块的名字 (一个字符串) 可以通过全局变量 __name__ 得到. 

创建一个名为 fibo.py 的文件, 并输入以下内容:

# Fibonacci 数列模块

def fib(n):    # 打印小于 n 的 Fibonacci 数列
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()

def fib2(n): # 返回小于 n 的 Fibonacci 数列
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a+b
    return result

访问模块中的函式(这样并不会把 fibo 中定义的函式名 导入(import) 到当前的符号表里; 它只导入了模块名 fibo. 你可以使用模块名来访问函式)

>>> 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'

 

模块不仅包含函式定义, 还可以包含可执行的语句. 这些语句一般用以初始化模块. 他们仅在模块 第一 次被导入时才被执行. [1]

模块中可以导入其它的模块. 习惯上把 import 语句放在一个模块 (或者脚本, ) 的最开始, 当然这只是惯例不是强制的. 被导入模块的名称被放入当前模块的全局符号表里.

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 程序员不使用这个窍门, 因为它导入了一些未知的名字到解释器里, 因此可能会意外重载一些你已经定义的东西.

 

把模块当成脚本来使用

模块有一些内置属性,用于完成特定的任务,如__name__、__doc__。每个模块都有一个名称。

例如:

__name__用于判断当前模块是否是程序的入库,如果当前程序正在被使用,__name__的值为“__main__”。通常给每个模块都添加一个条件语句,用于单独测试该模块的功能。

当你以如下方式运行一个 Python 模块时

python fibo.py <arguments>

模块中的代码就会被执行, 就像被导入时一样, 但 __name__ 被设为 "__main__" . 这就意味着通过在模块最后加入以下代码:

if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))

 

导入包

包就是一个完成特定任务的工具箱,为了实现程序的重用。把实现一个常用功能的代码组合到一个包中,调用包提供的服务从而实现重用。Python提供了许多有用的工具包,如字符串处理、图形用户接口、Web应用、图形图像处理等。这些自带的工具包和模块安装在Python的安装目录下的Lib子目录中。

包必须至少含有一个__int__.py文件按,该文件的内容可以为空。__int__.py用于标识当前文件夹是一个包。

 

导入模块

可以通过sys.path语句搜索模块的查找路径。当Python导入一个模块时,Python首先查找当前路径,然后查找lib目录、site-packages目录(Python\Lib\site-packages)和环境变量PATHONPATH设置的目录。如果导入的模块没有找到,手动在以上路径搜索一下是否含有这个模块。

 

导入包的常用方式

导入子模块

from sound.effects import echo

可以这样使用

echo.echofilter(input, output, delay=0.7, atten=4)

或者直接导入想要的函式或变量:

from sound.effects.echo import echofilter

* 注意: Python中的import语句比Java的import语句更加灵活。Python的import语句可以置于程序中任意的位置,甚至可以放在条件语句中。

 

从包中导入 *

当开发者写下 from sound.effects import * 会发生什么?

理想地, 我们期望程序会以以某种方法进入文件系统, 寻找在指定的包文件中,找到所有子模块, 并把它们全部导入. 这可能花费很长的时间, 而且对子模块进行显式导入时,还可能引发非期待的 副作用!

对于包作者, 唯一解决方案是提供包的显式索引. import 语句有以下约定:

  • 如果一个包的 __init__.py 代码定义了一个名为 __all__ 的列表,
  • 当遇到 from package import * 时, 它被用来作为导入的模块名字的列表.

例如, 文件 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.echo
import sound.effects.surround
from sound.effects import *

在这个例子中, 模块 echo 和 surround 被导入到当前命名空间, 因为当 执行 from...import 语句时它们就被定义在包 sound.effects 里. (当定义 __all__ 定义时, 这也会工作.)

虽然有些模块被设计成当使用 import * 时仅导出遵循特定模式的名称, 但是在产品代码中仍然感觉算糟糕实践.

记住, 使用 from Package import specific_submodule 是没有问题的! 事实上, 这是推荐的用法, 只在以下情况例外: 正在导入的模块需要使用的子模块与其他包中的子模块具有相同的名字.

 

相对包导入

你还可以使用相对导入, 通过 import 语句的 from module import name 格式. 这些导入使用句点来表明涉及这次相对导入的当前包和父包. 从例子中的 surround , 您可以使用

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

注意, 相对导入基于当前模块的名字. 因为主模块的名字总是 "__main__", 有意用作一个 Python 程序的主模块的模块必须总使用 绝对导入 .

© 著作权归作者所有

共有 人打赏支持
lemos
粉丝 6
博文 178
码字总数 90986
作品 0
芜湖
后端工程师
如何简单地理解 Python 中的 if __name__ == '__main__'

昨天的分享:用 Python 带你看《我不是药神》 源码链接:https://pan.baidu.com/s/1Gnxc2iTWHrS7tGEveO4hQ 密码:27op 1. 摘要 通俗的理解name == 'main':假如你叫小明.py,在朋友眼中,你是...

xjtuhit
07/20
0
0
关于 python ImportError: No module named 的问题

今天在 centos 下安装 python setup.py install 时报错:ImportError: No module named sysconfig, 当时急着用,就顺手直接源码编译了一把,make install 后就 ok 了。 然后又在 cygwin 下安...

大数据之路
2013/02/21
0
8
【转载】如何制作python安装模块(setup.py)

Python 模块的安装方法: 单文件模块:直接把文件拷贝到 $PYTHON_DIR/lib 多文件模块,且带有 setup.py :只需执行 python setup.py install egg 文件:1) 下载 ezsetup.py ,运行 python e...

摩云飞
2013/01/04
0
0
python 脚本的启动模式(python -m以模块方式启动)

今天再看python的项目时,发现GitHub中给出的python脚本的执行格式是python -m pip install somepackage。于是开始了python模式启动之旅。 其中很多相关借鉴了该博客,同时感谢博主:http://...

wonengguwozai
05/28
0
0
《Python从小白到大牛》第4章 Python语法基础

本章主要为大家介绍Python的一些语法,其中包括标识符、关键字、常量、变量、表达式、语句、注释、模块和包等内容。 标识符和关键字 任何一种计算机语言都离不开标识符和关键字,因此下面将详...

tony关东升
06/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Java的快速失败和安全失败

一:快速失败(fail—fast) 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加、删除、修改),则会抛出Concurrent Modification Exception。 原理:迭代器在...

狼王黄师傅
2分钟前
0
0
Echarts X轴Y轴配置参数详情

mytextStyle={ color:"#333", //文字颜色 fontStyle:"normal", //italic斜体 oblique倾斜 fontWeight:"normal", //文字粗细bold bolder lighter 100 | 200 | 300 | 400... fontFamily:"sans......

wqzbxh
4分钟前
0
0
解决kettle使用JDBC读取Oracle速度慢的问题

jdbc连接添加如下信息: defaultRowPrefetch=20000

了凡川
8分钟前
0
0
Linux学习-1015

8.10 shell特殊符号cut命令 8.11 sort_wc_uniq命令 8.12 tee_tr_split命令 8.13 shell特殊符号下 相关测验题目:题目:http://ask.apelearn.com/question/5437 扩展 扩展 1. source exec 区别...

wxy丶
9分钟前
0
0
Spring Boot核心注解讲解

Spring Boot核心注解讲解 Spring Boot最大的特点是无需XML配置文件,能自动扫描包路径装载并注入对象,并能做到根据classpath下的jar包自动配置。 所以Spring Boot最核心的3个注解就是: 1,...

DemonsI
15分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部