Python基础之:Python中的模块
文章目錄
- 簡介
- 模塊基礎(chǔ)
- 執(zhí)行模塊
- 模塊搜索路徑
- dir
- 包
- 包的相對路徑
簡介
Python的解釋環(huán)境是很好用,但是如果我們需要編寫一個(gè)大型的程序的時(shí)候,解釋環(huán)境就完全不夠用了。這個(gè)時(shí)候我們需要將python程序保存在一個(gè)文件里。通常這個(gè)文件是以.py結(jié)尾的。
對于大型的應(yīng)用程序來說,一個(gè)文件可能是不夠的,這個(gè)時(shí)候我們需要在文件中引用其他的文件,這樣文件就叫做模塊。
模塊是一個(gè)包含Python定義和語句的文件。文件名就是模塊名后跟文件后綴 .py 。在模塊內(nèi)部,模塊名可以通過全局變量 __name__ 獲得。
模塊基礎(chǔ)
還是之前的斐波拉赫數(shù)列的例子,我們在fibo.py文件中存放了函數(shù)的實(shí)現(xiàn):
def fib(n): # write Fibonacci series up to na, b = 0, 1while a < n:print(a, end=' ')a, b = b, a+bprint()編寫完畢之后,我們可以在Python的解釋環(huán)境中導(dǎo)入它:
>>> import fibo然后直接使用即可:
>>> fibo.fib(1000) 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987常用的函數(shù),我們可以將其賦值給一個(gè)變量:
>>> fib = fibo.fib >>> fib(1000) 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987或者,我們在導(dǎo)入的時(shí)候,直接給這個(gè)模塊起個(gè)名字:
>>> import fibo as fib >>> fib.fib(500) 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377或者導(dǎo)入模塊中的函數(shù):
>>> from fibo import fib as fibonacci >>> fibonacci(500) 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377每個(gè)模塊都有它自己的私有符號表,該表用作模塊中定義的所有函數(shù)的全局符號表。因此,模塊的作者可以在模塊內(nèi)使用全局變量,而不必?fù)?dān)心與用戶的全局變量發(fā)生意外沖突。
執(zhí)行模塊
前面我們提到了可以使用import來導(dǎo)入一個(gè)模塊,并且 __name__ 中保存的是模塊的名字。
和java中的main方法一樣,如果我們想要在模塊中進(jìn)行一些測試工作,有沒有類似java中main方法的寫法呢?
先看一個(gè)例子:
if __name__ == "__main__":import sysfib(int(sys.argv[1]))在模塊中,我們需要進(jìn)行一個(gè)判斷 __name__ 是不是被賦值為 "__main__"。
我們這樣來執(zhí)行這個(gè)模塊:
python fibo.py <arguments>以腳本執(zhí)行的情況下,模塊的 __name__ 屬性會(huì)被賦值為 __main__ , 這也是例子中為什么要這樣寫的原因。
看下執(zhí)行效果:
$ python fibo.py 50 0 1 1 2 3 5 8 13 21 34如果是以模塊導(dǎo)入的話,那么將不會(huì)被執(zhí)行:
>>> import fibo >>>模塊搜索路徑
使用import導(dǎo)入模塊的時(shí)候,解釋器首先會(huì)去找該名字的內(nèi)置模塊,如果沒找到的話,解釋器會(huì)從 sys.path變量給出的目錄列表里尋找。
sys.path的初始目錄包括:
- 當(dāng)前目錄
- PYTHONPATH 指定的目錄
- 安裝的默認(rèn)值
dir
要想查看模塊中定義的內(nèi)容,可以使用dir函數(shù)。
>>> a = [1, 2, 3, 4, 5] >>> import fibo >>> fib = fibo.fib >>> dir() ['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']上面的例子列出了當(dāng)前模塊中定義的內(nèi)容,包括變量,模塊,函數(shù)等。
注意, dir() 不會(huì)列出內(nèi)置函數(shù)和變量的名稱。如果你想要這些,它們的定義是在標(biāo)準(zhǔn)模塊 builtins 中。
我們可以給dir加上參數(shù),來獲取特定模塊的內(nèi)容:
>>> import builtins >>> dir(builtins) ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException','BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning','ChildProcessError', 'ConnectionAbortedError', 'ConnectionError','ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning','EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False','FileExistsError', 'FileNotFoundError', 'FloatingPointError','FutureWarning', 'GeneratorExit', 'IOError', 'ImportError','ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError','IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError','MemoryError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented','NotImplementedError', 'OSError', 'OverflowError','PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError','ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning','StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError','SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError','UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError','UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning','ValueError', 'Warning', 'ZeroDivisionError', '_', '__build_class__','__debug__', '__doc__', '__import__', '__name__', '__package__', 'abs','all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable','chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits','delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit','filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr','hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass','iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview','min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property','quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice','sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars','zip']包
java中有package的概念,用來隔離程序代碼。同樣的在Python中也有包。
我們看一個(gè)Python中包的例子:
sound/ Top-level package__init__.py Initialize the sound packageformats/ Subpackage for file format conversions__init__.pywavread.pywavwrite.pyaiffread.pyaiffwrite.pyauread.pyauwrite.py...effects/ Subpackage for sound effects__init__.pyecho.pysurround.pyreverse.py...filters/ Subpackage for filters__init__.pyequalizer.pyvocoder.pykaraoke.py...上面我們定義了4個(gè)包,分別是sound,sound.formats, sound.effects, sound.filters。
注意,如果是包的話,里面一定要包含 __init__.py 文件。
__init__.py 可以是一個(gè)空文件,也可以執(zhí)行包的初始化代碼或設(shè)置 __all__ 變量。
當(dāng)導(dǎo)入的時(shí)候, python就會(huì)在 sys.path 路徑中搜索該包。
包的導(dǎo)入有很多種方式,我們可以導(dǎo)入單個(gè)模塊:
import sound.effects.echo但是這樣導(dǎo)入之后,使用的時(shí)候必須加載全名:
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)如果不想加載全名,可以這樣導(dǎo)入:
from sound.effects import echo那么就可以這樣使用了:
echo.echofilter(input, output, delay=0.7, atten=4)還可以直接導(dǎo)入模塊中的方法:
from sound.effects.echo import echofilter然后這樣使用:
echofilter(input, output, delay=0.7, atten=4)如果一個(gè)包里面的子包比較多,我們可能會(huì)希望使用 * 來一次性導(dǎo)入:
from sound.effects import *那么如何去控制到底會(huì)導(dǎo)入effects的哪一個(gè)子包呢?
我們可以在 __init__.py 中定義一個(gè)名叫 __all__ 的列表,在這個(gè)列表中列出將要導(dǎo)出的子包名,如下所示:
__all__ = ["echo", "surround", "reverse"]這樣from sound.effects import * 將導(dǎo)入 sound 包的三個(gè)命名子模塊。
如果沒有定義 __all__,from sound.effects import * 語句 不會(huì) 從包 sound.effects 中導(dǎo)入所有子模塊到當(dāng)前命名空間;它只會(huì)導(dǎo)入包 sound.effects。
包的相對路徑
Import 可以指定相對路徑,我們使用 . 來表示當(dāng)前包, 使用 … 來表示父包。
如下所示:
from . import echo from .. import formats from ..filters import equalizer本文已收錄于 http://www.flydean.com/07-python-module/
最通俗的解讀,最深刻的干貨,最簡潔的教程,眾多你不知道的小技巧等你來發(fā)現(xiàn)!
歡迎關(guān)注我的公眾號:「程序那些事」,懂技術(shù),更懂你!
超強(qiáng)干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生總結(jié)
以上是生活随笔為你收集整理的Python基础之:Python中的模块的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ES6中的新特性:Iterables和i
- 下一篇: Python基础之:Python中的IO