Python模塊
模塊允許邏輯地組織Python代碼。 將相關代碼分組到一個模塊中,使代碼更容易理解和使用。 模塊是一個具有任意命名屬性的Python對象,可以綁定和引用。
簡單來說,模塊是一個由Python代碼組成的文件。模塊可以定義函數,類和變量。 模塊還可以包括可運行的代碼。
示例
下面是一個名稱爲aname
的模塊的Python代碼通常位於一個名稱爲aname.py
的文件中。以下是一個簡單模塊的例子:support.py
-
def print_func( par ):
print "Hello : ", par
return
1.import語句
可以通過在其他Python源文件中執行import
語句來將任何Python源文件用作模塊。導入具有以下語法 -
import module1[, module2[,... moduleN]
當解釋器遇到導入語句時,如果模塊存在於搜索路徑中,則導入該模塊。搜索路徑是導入模塊之前解釋器搜索的目錄的列表。例如,要導入模塊hello.py
,需要將以下命令放在腳本的頂部 -
#!/usr/bin/python3
# Import module support
import support
# Now you can call defined function that module as follows
support.print_func("Maxsu")
當執行上述代碼時,會產生以下結果 -
Hello : Maxsu
不管模塊被導入多少次,模塊只能加載一次。這樣可以防止模塊執行重複發生,如果有多個導入。
2.from…import語句
Python from
語句允許將模塊中的特定屬性導入到當前的命名空間中。 from...import
具有以下語法 -
from modname import name1[, name2[, ... nameN]]
例如,要從模塊 fib
導入函數fibonacci
,請使用以下語句 -
#!/usr/bin/python3
# Fibonacci numbers module
def fib(n): # return Fibonacci series up to n
result = []
a, b = 0, 1
while b < n:
result.append(b)
a, b = b, a + b
return result
>>> from fib import fib
>>> fib(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
此語句不會將整個模塊fib
導入到當前命名空間中; 它只是將fibonacci
從模塊fib
引入導入模塊的全局符號表。
3.from…import *語句
也可以使用以下import
語句將模塊中的所有名稱導入到當前命名空間中 -
from modname import *
這提供了將所有項目從模塊導入到當前命名空間中的簡單方法; 但是,這個說法應該謹慎使用。
4.執行模塊作爲腳本
在模塊中,模塊的名稱(作爲字符串)可用作全局變量__name__
的值。模塊中的代碼將被執行,就像您導入它一樣,但是__name__
設置爲「__main__
」。
在模塊的最後添加這個代碼 -
#!/usr/bin/python3
# Fibonacci numbers module
def fib(n): # return Fibonacci series up to n
result = []
a, b = 0, 1
while b < n:
result.append(b)
a, b = b, a + b
return result
if __name__ == "__main__":
f = fib(100)
print(f)
運行上述代碼時,將顯示以下輸出。
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
5.定位模塊
當導入模塊時,Python解釋器將按以下順序搜索模塊 -
- 當前目錄。
- 如果沒有找到該模塊,Python會在shell變量
PYTHONPATH
中搜索每個目錄。 - 如果其他所有失敗,Python將檢查默認路徑。 在UNIX上,此默認路徑通常是
/usr/local/lib/python3/
或者/usr/sbin/
模塊搜索路徑作爲sys.path
變量存儲在系統模塊sys
中。sys.path
變量包含當前目錄PYTHONPATH
和依賴於安裝的默認值。
6.PYTHONPATH變量
PYTHONPATH
是一個環境變量,由目錄列表組成。 PYTHONPATH
的語法與shell變量`PATH```的語法相同。
這是一個典型的Windows系統上的PYTHONPATH
-
set PYTHONPATH = c:\python34\lib;
這裏是UNIX系統的典型PYTHONPATH
-
set PYTHONPATH = /usr/local/lib/python
7.命名空間和範圍
變量是映射到對象的名稱(標識符)。 命名空間是變量名(鍵)及其對應對象(值)的字典。
- Python語句可以訪問本地命名空間和全局命名空間中的變量。如果本地和全局變量具有相同的名稱,則局部變量會影響全局變量。
- 每個函數都有自己的本地命名空間。 類方法遵循與普通函數相同的範圍規則。
- Python對於變量是本地還是全局都進行了有根據的判斷。它假定在函數中分配值的任何變量都是本地的。
- 因此,爲了將值分配給函數內的全局變量,必須首先使用
global
語句。 - 語句
global VarName
告訴PythonVarName
是一個全局變量。Python停止搜索本地命名空間的變量。
例如,在全局命名空間中定義一個變量Money
。 在函數Money
中爲Money
賦值,因此Python將Money
作爲局部變量。
但是,如果在設置之前就訪問了本地變量Money
的值,它會產生一個錯誤:UnboundLocalError
。 這裏可以通過取消註釋global
語句來解決問題。如下示例代碼 -
#!/usr/bin/python3
Money = 2000
def AddMoney():
# Uncomment the following line to fix the code:
# global Money
Money = Money + 1
print (Money)
AddMoney()
print (Money)
8.dir( )函數
dir()
內置函數返回一個包含由模塊定義的名稱的字符串的排序列表。這個列表包含模塊中定義的所有模塊,變量和函數的名稱。 以下是一個簡單的例子 -
#!/usr/bin/python3
# Import built-in module math
import time
content = dir(time)
print (content)
當執行上述代碼時,會產生以下結果 -
['_STRUCT_TM_ITEMS', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'altzone', 'asctime', 'clock', 'ctime', 'daylight', 'get_clock_info', 'gmtime', 'localtime', 'mktime', 'monotonic', 'perf_counter', 'process_time', 'sleep', 'strftime', 'strptime', 'struct_time', 'time', 'timezone', 'tzname']
這裏,特殊的字符串變量__name__
是模塊的名稱,__file__
是加載模塊的文件名。
9.globals()和locals()函數
globals()
和locals()
函數可用於返回全局和本地命名空間中的名稱,具體取決於它們被調用的位置。
- 如果
locals()
從一個函數中調用,它將返回從該函數本地訪問的所有名稱。 - 如果從函數中調用
globals()
,它將返回從該函數全局訪問的所有名稱。
這兩個函數的返回類型是字典。 因此,可以使用keys()
函數提取名稱。
10.reload()函數
當將模塊導入到腳本中時,模塊的頂級部分的代碼只能執行一次。
因此,如果要重新執行模塊中的頂級代碼,可以使用reload()
函數。reload()
函數再次導入以前導入的模塊。 reload()
函數的語法是這樣的 -
reload(module_name)
這裏,module_name
是要重新加載的模塊的名稱,而不是包含模塊名稱的字符串。 例如,要重新加載hello
模塊,請執行以下操作 -
reload(hello)
11.Python中的包
Python中的包是一個分層文件目錄結構,它定義了一個由模塊和子包和子子包組成的Python應用程序環境,等等。
在package
目錄中創建兩個目錄:pkg
和pkg2
, 然後分別在這兩個目錄中創建兩個文件:a.py
和b.py
。該文件具有以下一行源代碼 -
文件: pkg/a.py -
#!/usr/bin/python3
#coding=utf-8
# save file: pkg/a.py
def fun():
print ("I'm pkg.a.fun() ")
文件: pkg/b.py -
#!/usr/bin/python3
#coding=utf-8
# save file: pkg/b.py
def fun():
print ("I'm pkg.b.fun() ")
文件: pkg2/a.py -
#!/usr/bin/python3
#coding=utf-8
# save file: pkg2/a.py
def fun():
print ("I'm pkg2.a.fun() ")
文件: pkg2/b.py -
#!/usr/bin/python3
#coding=utf-8
# save file: pkg2/b.py
def fun():
print ("I'm pkg2.b.fun() ")
在package
目錄中創建一個主程序文件:main.py
,用於演示如何調用包中的各個文件 -
#!/usr/bin/python3
#coding=utf-8
# save file: phone/pots.py
import pkg.a as a
import pkg.b as b
import pkg2.a as a2
import pkg2.b as b2
a.fun()
b.fun()
a2.fun()
b2.fun()
import pkg2.a
import pkg2.b
print('----------- another way -----------------')
pkg2.a.fun()
pkg2.b.fun()
整個代碼的目錄如下所示 -
package
|- pkg
|- __init__.py
|- a.py
|- b.py
|- pkg2
|- __init__.py
|- a.py
|- b.py
當執行上述代碼時,會產生以下結果 -
I'm pkg.a.fun()
I'm pkg.b.fun()
I'm pkg2.a.fun()
I'm pkg2.b.fun()
----------- another way -----------------
I'm pkg2.a.fun()
I'm pkg2.b.fun()
在上面的例子中,將每個文件中的一個函數作爲示例,但是可以在文件中編寫多個函數。還可以在這些文件中定義不同的Python類,然後可以使用這些類來創建包。