欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python3 模块

程序员文章站 2022-06-12 22:46:16
...

一、基本定义

  • 模块是把一些 定义存放 在文件中,为一些脚本或者交互式的解释器实例使用
  • 模块是一个 包含所有定义的函数和变量的文件 ,其后缀名是 .py
  • 模块可以 被别的程序引入 ,以使用该模块中的函数等功能

二、import 语句

  • 当解释器遇到 import 语句,模块在当前的搜索路径就会 被导入
  • 搜索路径 是一个解释器会先进行搜索的所有目录的列表
# 一般形式
import module1, module2, ..., moduleN
# 该实例演示创建模块和导入模块

# 创建 fibo.py 斐波那契(fibonacci)数列模块
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


# 导入 fibo.py 斐波那契(fibonacci)数列模块
>>> 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'

二、from … import 语句

  • 从模块中导入一个 指定的部分 到当前命名空间中
# 一般形式
from modname import name1, name2, ..., nameN
# 这个声明不会把整个 fibo 模块导入到当前的命名空间中,它只会将模块里的 fib 函数引入进来
>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

三、from … import * 语句

  • 从一个模块的 所有内容全都导入 到当前的命名空间也是可行的,
  • 然而这种声明 不该被过多地使用 ,因为那些由单一下划线 _ 开头的名字 不在此例
  • 大多数情况, Python 程序员 不使用 这种方法,因为引入的其它来源的命名,很可能覆盖 已有的定义
# 一般形式
from modname import *

四、__name__属性

  • 一个模块被另一个程序 第一次引入时 ,其主程序将运行
  • 也可以在模块 被引入时 ,控制模块中的某一程序块不执行
# 创建 using_name.py
if __name__ == '__main__':
	print('程序自身在运行')
else:
	print('我来自另一模块')

$ python using_name.py
程序自身在运行

>>> import using_name
我来自另一模块

五、dir() 函数

  • 可以找到模块内定义的 所有名称
# 简单实例
>>> import keyword
>>> dir(keyword)
['__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'iskeyword', 'kwlist', 'main']
# 如果没有给定参数,就会罗列出当前定义的所有名称
>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir()  # 得到一个当前模块中定义的属性列表
['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']
>>> a = 5  # 建立一个新的变量 'a'
>>> dir()
['__builtins__', '__doc__', '__name__', 'a', 'sys']
>>>
>>> del a  # 删除变量名 'a'
>>>
>>> dir()
['__builtins__', '__doc__', '__name__', 'sys']

六、标准模块

https://docs.python.org/3/library/index.html

七、包

  • 一种管理 Python 模块命名空间的形式,采用 点模块名称不用担心 不同库之间的模块重名的情况
  • 在导入一个包的时候,Python 3.x 会根据 sys.path 中的目录来寻找当前包里所包含的子目录
  • 目录只有包含一个叫做 __init__.py 的文件才会被认作是一个包,主要是为了 避免一些滥俗的名字 影响搜索路径中的有效模块
  • 最简单的情况,放一个空的 :file:__init__.py,当然这个文件中也可以包含一些初始化代码或者为 __all__ 变量赋值
# 该实例演示一种可能的包结构(在分层的文件系统中)
sound/                          顶层包
      __init__.py               初始化 sound 包
      formats/                  文件格式转换子包
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  声音效果子包
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  filters 子包
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...
# 用户可以每次只导入一个包里面的特定模块
import sound.effects.echo

# 以上必须使用全名去访问被导入的子模块
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

# 另一种导入子模块的方法
from sound.effects import echo

# 不需要冗长的前缀导入子模块
echo.echofilter(input, output, delay=0.7, atten=4)

# 直接导入子模块的一个函数或者变量
from sound.effects.echo import echofilter

# 导入子模块,可以直接使用他的 echofilter() 函数
echofilter(input, output, delay=0.7, atten=4)

Explain:

  • 当使用 from package import item 形式,item 既可以是包里面的子模块(子包),或者包里面定义的其他名称,比如函数,类或者变量
  • 当使用 import item.subitem.subsubitem 形式,subsubitem 既可以是模块或者是包,但是不可以是类,函数或者变量的名字,其他项都必须是包

七、从一个包中导入 *

  • Python 3.x 中,会进入文件系统,找到这个包里面所有的子模块,一个一个 的把它们都导入进来
  • 这个方法在 Windows 平台上工作的就不是非常好,因为这是一个 大小写不区分 的系统,无法精确导入模块
  • 为了解决这个问题,只能创建一个精确的包的索引 ,在定义文件 __init__.py 存在一个叫做 __all__ 的列表变量,在使用 from package import * 的时候就把这个列表中的 所有名字作为包内容导入
  • 可别忘了在更新包之后 保证 __all__ 也更新
# 在 :file:sounds/effects/__init__.py 变量赋值
__all__ = ["echo", "surround", "reverse"]

Explain:

  • 并不主张使用 from package import * 这种方法来导入模块,因为这种方法经常会导致代码的 可读性降低
  • 推荐使用 from package import specific_submodule ,除非是你要导入的子模块有可能和其他包的子模块重名,必须使用 绝对路径 来导入特定模块
  • 无论是隐式的还是显式的相对导入都是 从当前模块开始的
  • 主模块的名字永远是 __main__ ,一个 Python 应用程序的主模块,应当总是使用 绝对路径 引用
  • 包还提供一个额外的目录列表属性 __path__ ,里面每一个包含的目录 都有 为这个包服务的 __init__.py ,可以修改这个变量,用来影响包含在包里面的模块和子包,这个功能并不常用,一般用来 扩展 包里面的模块