「学习笔记——Python」Python 的模块(Modules)

6 Python的模块 (Modules)

1 关于模块

如果你退出了交互模式,那么你定义的东西都都没啦!如果你要写一个长一点的程序,那么最好写在一个文件里,每次需要 运行时就运行一下这个文件,这文件叫做脚本(Scripts)。随着程序变大,写在一个文件里也不行了,你需要把它分割成多个部分,以 方便维护和组织,这些不同的部分叫做模块(Modules)。 模块可以通过 import 来导入,这样我们就可以使用这个模块中定义的函数啦!一个文件对应一个模块,模块名是文件名去掉 扩展名。下面来看一个例子~

# Fibonacci sequence module

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

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

我们可以在交互模式下导入这个模块,然后使用其中的函数,同时模块内还有一个全局变量,以 __ name __ 表示。

>>> import fibo
>>> fibo.fib(10)
1 1 2 3 5 8
>>> fibo.fib(10)
1 1 2 3 5 8
>>> fibo.__name__
'fibo'

另外,如果经常使用这个函数,还可以将其赋给一个局部变量

>>> fib1= fibo.fib
>>> fib1(10)
1 1 2 3 5 8

1.1 更多关于模块的故事

模块不仅可以包含函数,还可以包含可执行语句,它们负责初始化模块,且仅在第一次导入模块时被执行。 每个模块都有其私有符号表,模块内的所有函数将它们当作全局符号表来使用。 一个模块可以导入(import)另一个模块,import语句习惯于在开始调用,但这并非必要。 下面这种方式将从另一个模块符号表里的内容导入本模块符号表的方式,导入之后,就可以像模块内函数那样使用它们

>>> from fibo import fib, fib2
>>> fib(300)
1 1 2 3 5 8 13 21 34 55 89 144 233
>>> fib2(200)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]
>>> fibo.fib(10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'fibo' is not defined

注意,并未导入fibo,所以不能使用fibo.fib来调用函数。

可以通过下面这种方式,导入另一个模块内所有的符号

>>> from fibo import *
>>> fib(10)
1 1 2 3 5 8
>>> fib2(10)
[1, 1, 2, 3, 5, 8]

1.2 将模块作为脚体执行

在命令行输入下面的内容会执行脚本的内容,

python fibo.py <arguments>

如果只想让脚本中的可执行语句在通过上述方式执行时起作用,而在交互模式 import 时不执行,可以在 脚本的最后加入:

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

原因就在于 命令行执行和交互模式 import 时,__ name __ 的值是不一样的,做一个小实验就会明白: 在 fibo.py 中加入

print __name__

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

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

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

在命令行执行时,

python fibo.py 10
__main__
1 1 2 3 5 8

在交互模式 import 时

>>> import fibo
fibo

1.3 模块搜索路径

当模块 spam 被导入时,解释器首先在内置模块中搜索这个名字,如果没有找到,会在 sys.path 指定的一系列目录下 查找 spam.py 这个文件,sys.path 会在这些地方初始化。

  • 包含当前脚本的目录(或者当前目录)
  • PYTHONPATH (一系列目录名,和系统变量PATH格式一样)
  • 安装时默认的设定(the installation-dependent default)

1.4 “编译过的” Python 文件

如果 spam.py 所在文件下有一个名为 spam.pyc 的文件存在,这说明有 spam.py 已经被编译过,编译后的字节码 存放在 spam.pyc 中。这是加速调用大量标准库的 python 程序启动时间的一项重要技术。 正常情况下,你无需为 spam.pyc 的产生做任何事情,当 spam.py 被成功编译时,会尝试写入 spam.pyc, 如果失败了, 那也不会报错,如果写入的信息不完整,spam.pyc会被认为是无效的。

2 标准模块

Python 自带了一个标准模块库,一些模块被内置于解释器中,这些模块不涉及语言的核心,但是与效率以及操作系统 相关,例如系统调用。这些模块在不同平台有所不同。 需要特别注意的是 sys 模块,它可以修改交互模式下的提示符,修改搜索路径,等等。

>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps1 = '>_:'
>_:sys.ps2
'... '
>_:sys.path.append('/usr/lib')

3 dir 函数

dir 函数可以得到一个模块定义了哪些名称,例如

>>> import fibo
fibo
>>> dir(fibo)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'fib', 'fib2']

注意 dir 会列出所有类型的名字:变量,函数,模块等等,不会列出内置的函数和变量,如果想查看内置变量,可以 用

>>> import __builtin__
>>> dir(__builtin__)
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BufferError', 
'BytesWarning', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 
'False', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 
'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 
'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented', 'NotImplementedError', 
'OSError', 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 
'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError',
 'SystemExit', 'TabError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 
'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 
'ValueError', 'Warning', 'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__', 
'__name__', '__package__', 'abs', 'all', 'any', 'apply', 'basestring', 'bin', 'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'chr', 
'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod',
'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']

4 包(Package)

包是 Python 组织模块名称空间的一种方式,例如模块名 A.B 表示包A中的子模块B. 例如你需要设计一系列模块用于处理声音文件和声音数据,文件有不同的格式,如wav,au,aiff. 数据处理方式也有很多种, 例如混合,合并,等等,那么,你可能需要这样设计和组织模块:

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

__ init __.py 文件可以用于加载模块前设置路径,设置变量等。 使用包中的模块时,可以这样使用

import 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
echofilter(input, output, delay=0.7, atten=4)

4.1 Import * from package

如果我们通过下面的方式导入,会有什么效果呢?

from sound.effects import *

理想情况下,它会导入包下的所有子模块,但实际上,它需要花费很长时间,并且有副作用。 解决这个问题的办法是,在__ init __.py 文件中定义一个变量,这样上述执行会根据这个变量的内容知道应该导入什么。

__all__ = ["echo", "surround", "reverse"]

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值