工作生活

Python 模块与包的导入问题

2019-07-03  本文已影响0人  Dozing

Python模块(Module)

下例子是Python官网上面的模块fibo.py

# Fibonacci numbers module

def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while a < n:
        print(a, end=' ')
        a, b = b, a+b
    print()

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

模块定义好后,我们可以使用import语句来引入模块

import module[,module2[,....module]]

例如要引用模块math,就可以在文件最开始的地方用import math来引入。调用math模块中的函数时,必须这样引用:模块名.函数名

导入模块中函数的方法

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

这会调入所有非以下划线(_)开头的名称。在多数情况下,Python程序员都不会使用这个功能,因为它在解释器中引入了一组未知的名称,而它们很可能会覆盖一些你已经定义过的东西。
注意通常情况下从一个模块或者包内调入*的做法是不太被接受的,因为这通常会导致代码的可读性很差。不过,在交互式编译器中为了节省打字可以这么用。

注:在模块当中定义一个变量__all__:
使用__all__的影响: 使用from 模块名 import *方式导入时只会导入
__all__列表[]里面函数名。 __all__如果没有这个变量将全部导入(__all__仅限 于from 模块名 import *这种导入方式)

例子:
加入__all__示例:

 __all__ = ["demo"]
 def demo():

     print("demo")

 def demo1():
     print("demo1")

运行结果:

>>> from TT import *
 
>>>demo()
demo
 
>>>demo1()
-----------------------------------------------------------------------
NameError                             Traceback (most recent call last)
<ipython-input-3-a8330644fa2e> in <module>()
----> 1 demo1()
 
NameError: name 'demo1' is not defined

不加__all__示例:

def demo():
    print("demo")
    
def demo1():
    print("demo1")

运行结果:

>>> from TT import *
>>> demo()
demo
>>> demo1()
demo1
>>> import fibo as fib
>>> fib.fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
>>> from fibo import fib as fibonacci
>>> fibonacci(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

注:处于效率的考虑,每个模块在每个解释器会话中只被导入了一次。因此,如果你更改了你的模块,则必须重新启动解释器。

以脚本的方式执行模块

当你用下面方式运行一个Python模块:

python fibo.py <arguments>

模块里的代码会被执行,就好像你导入了模块一样,但是 __name__被赋值为 __main__。 这意味着通过在你的模块末尾添加这些代码:

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

你既可以把这个文件当作脚本又可当作一个可调入的模块来使用, 因为那段解析命令行的代码只有在当模块是以main文件的方式执行的时候才会运行:

$ python fibo.py 50
0 1 1 2 3 5 8 13 21 34

如果模块是被导入的,那些代码是不运行的:

>>> import fibo
>>>

Python中的包

下例子是Python官网上面的例子:

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

导入包中函数,模块的方式:

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)

子包参考:

当包被构造成子包时(与示例中的 sound 包一样),你可以使用绝对导入来引用兄弟包的子模块。
你还可以使用import语句的 from module import name 形式编写相对导入。这些导入使用前导点来指示相对导入中涉及的当前包和父包。例如,从 surround 模块,你可以使用:

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

相对导入是基于当前模块的名称进行导入的。由于主模块的名称总是 "__main__" ,因此用作Python应用程序主模块的模块必须始终使用绝对导入。

上一篇下一篇

猜你喜欢

热点阅读