除了內置對象,標準庫對象和擴展庫對象在使用前都需要用 import 導入。
一、導入模塊
(1)基本語句:import 模塊名 [as 模塊別名]
導入模塊後就可以使用模塊中的類、函數、對象等東東了,不過在使用時要加上“模塊名.”這個前綴。爲了簡化前綴,在導入時可以用“as 模塊別名”的方式,給模塊取個別名。不過取了別名之後,原名就失效了。例如:
import datetime
d = datetime.date.today()
t = datetime.datetime.now()
print(d,t) # 2020-02-03 2020-02-03 11:35:20.937157
print(dir(datetime)) # 查看模塊中的所有對象:['MAXYEAR',... 'tzinfo']
print(dir(datetime.date)) # 查看類中所有成員:['__add__',... 'weekday', 'year']
import datetime as dt # 給datetime取個別名
d01 = dt.date.today()
t01 = dt.datetime.now()
print(d01,t01) # 2020-02-03 2020-02-03 11:37:21.739067
d02 = datetime.date.today() # 原名失效:NameError: name 'datetime' is not defined
(2)同時導入多個模塊:import 模塊1名 [as 模塊1別名], 模塊2名 [as 模塊2別名], …
例如:
import os, sys , datetime as dt, math # 同時導入 os、sys、datetime、math
print(dt.date.today(), math.ceil(2.98)) # 2020-02-03 3
二、導入模塊中的對象
(1)基本語句:from 模塊名 import 對象名 [as 對象別名]
這種方式導入的不是整個模塊中的所有對象,而是指定的對象。通過這種方式導入的對象,在使用時,不需要加上“模塊名.”這個前綴。當然,這也帶來一個問題:在導入多個模塊的情況下,如果有對象重名的現象,重名的對象會相互屏蔽。在導入時也可以給對象另取別名。例如:
from datetime import date # 僅導入 date
print(date.today()) # 2020-02-03
print(datetime.date.today()) # 不要前綴:NameError: name 'datetime' is not defined
print(datetime.now()) # 沒有導入:NameError: name 'datetime' is not defined
(2)同時導入多個對象:from 模塊名 import 對象1名 [as 對象1別名], 對象2名 [as 對象2別名], …
例如:
from datetime import date as dd, datetime as tt
print(dd.today(), tt.now()) # 2020-02-03 2020-02-03 12:57:32.903249
(3)導入模塊中的所有對象:from 模塊名 import *
例如:
from datetime import *
print(date.today(), datetime.now()) # 2020-02-03 2020-02-03 12:59:41.594610
三、導入自定義的模塊
導入自定義模塊與導入標準庫模塊的語句是一樣的,但因爲標準庫模塊是系統自己存放的,且一般統一放在固定的目錄中,所以,導入時一般不用考慮路徑問題,而自定義的模塊就不一樣了,如果不弄清楚模塊的存放目錄,系統就會找不到模塊文件,從而使導入失敗。
在import 語句中是不可以指定模塊所在目錄的。例如: mport c:/mymod,這個語句是錯誤的。
1、當前目錄
系統在導入模塊時,首先在當前目錄中查找模塊文件。例如:在命令行窗口中,提示符爲:D:\py>,則首先在 D:\py 目錄中查找模塊文件,找到了模塊文件就立即導入。
2、sys.path 中列出的目錄
系統如果在當前目錄中沒有找到模塊文件,則在查看 sys.path 中列出的目錄,然後按照前後順序,在各個目錄中查找,找到了就導入,找不到就拋出異常:ModuleNotFoundError。
(1)查看 sys.path 中已有哪些目錄:print(sys.path)。
例如:
import sys
print(sys.path) # ['D:\\py\\python38.zip', 'D:\\py']
(2)在 sys.path 目錄列表的最後添加目錄:sys.path.append(目錄名)。
例如:
import sys
sys.path.append('D:\\aa')
sys.path.append('D:\\bb')
sys.path.append('D:\\cc')
print(sys.path) # ['D:\\py\\python38.zip', 'D:\\py', 'D:\\aa', 'D:\\bb', 'D:\\cc']
(3)在 sys.path 目錄列表的指定序號前插入目錄:sys.path.insert(序號,目錄名)
例如:
import sys;
sys.path.append('D:\\aa')
sys.path.insert(2,'D:\\dd')
sys.path.insert(0,'D:\\ee')
print(sys.path) # ['D:\\ee', 'D:\\py\\python38.zip', 'D:\\py', 'D:\\dd', 'D:\\aa']
在設置好目錄後,就可以導入自定義的模塊了。例如:
建立文件:E:\testpy\py05.py ,內容如下:
class c01:pass
class c02:pass
def fun01():pass
def fun02():pass
導入 p05 模塊:
import sys
sys.path.append('E:\\testpy')
import py05
print(dir(py05))
# ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__',
# '__package__', '__spec__', 'c01', 'c02', 'fun01', 'fun02']
print(sys.path) # ['D:\\py\\python38.zip', 'D:\\py', 'E:\\testpy']
四、導入自定義包
假設有以下自定義的包和模塊:
pybao(E:/testpy/)
__init__.py
baopy01.py
baopy02.py
pybao01
__init__.py
pybao02
__init__.py
baopy03.py
baopy04.py
pybao11
__init__.py
baopy05.py
pybao12
__init__.py
baopy06.py
baopy07.py
baopy08.py
baopy09.py
也就是說:
E:/testpy目錄中有:pybao包
pybao包中有:pybao01包、pybao02包
pybao02包中有:pybao11包、pybao12包
(1)基本語句:import 包名
與導入自定義模塊一樣,導入自定義包也有一個定位問題。系統同樣是先在當前目錄中查找,找不到就查看 sys.path 中列出的目錄,然後按照前後順序,在各個目錄中查找,再找不到就拋出異常。
“import 包名” 這一語句並不是將包中的所有模塊和對象導入,它唯一的結果是促使包中的 “__ init__.py” 被執行。
例如:E:/testpy/pybao/init.py 的內容爲:
print('This is __init__.py of pybao')
import sys
sys.path.append('E:\\testpy')
import pybao # This is __init__.py of pybao
“__ init__.py”被執行之後,如果在這個文件中有導入的語句,則相應的模塊和對象,就會被導入。例如:E:/testpy/pybao/__ init__.py 的內容爲:
print('This is __init__.py of pybao')
import sys
sys.path.append('E:\\testpy\\pybao')
import baopy01,baopy02
以這種方式導入的模塊,在引用時要加上“包名.”這個前綴,例如:
import sys
sys.path.append('E:\\testpy')
import pybao # This is __init__.py of pybao
print(dir(pybao.baopy01)) # [... 'c11', 'c12', 'fun11', 'fun12']
print(dir(pybao.baopy02)) # [... 'c21', 'c22', 'fun21', 'fun22']
總之,“import 包名” 不會直接導入任何的模塊和對象,只會觸發包中的 __ init__.py 文件被執行。
(2)導入包中的包:import 大包名.小包名. …
在導入過程中,大包、小包中的 __ init__.py 文件的都會被執行。例如:
E:/testpy/pybao/__ init__.py 的內容爲:
print('This is __init__.py of pybao')
E:/testpy/pybao02/__ init__.py 的內容爲:
print('This is __ init__.py of pybao02')
E:/testpy/pybao12/__ init__.py 的內容爲:
print('This is __init__.py of pybao12')
導入包:pybao12
import sys
sys.path.append('E:\\testpy')
import pybao.pybao02.pybao12
# 顯示:
# This is __init__.py of pybao
# This is __init__.py of pybao02
# This is __init__.py of pybao12
(3)直接導入包中的模塊:import 包名.模塊名
在導入過程中,包中的 __ init__.py 文件的會先被執行,然後導入包。例如:
E:/testpy/pybao/init.py 的內容爲:
print('This is __init__.py of pybao')
導入 pybao 包中的 baopy01.py 模塊:
import sys
sys.path.append('E:\\testpy')
import pybao.baopy01 # This is __init__.py of pybao
print(dir(pybao.baopy01)) # [... 'c11', 'c12', 'fun11', 'fun12']
以這種方式導入的模塊,在引用時也要加上“包名.”這個前綴,例如:
(4)直接導入包中的多個模塊:from 包名 import *
這一語句不是直接導入包中的所有模塊,而導入 “__ init__.py” 文件中, __ all__變量指定的模塊。例如:
E:/testpy/pybao/pybao02/pybao12/init.py 的內容爲:
print('This is __init__.py of pybao12')
__all__=[baopy05,baopy06]
導入pybao12的模塊:
import sys
sys.path.append('E:\\testpy')
from pybao.pybao02.pybao12 import *
# 顯示:
# This is __init__.py of pybao
# This is __init__.py of pybao02
# This is __init__.py of pybao12
print(dir(baopy05)) # [... 'c51', 'c52', 'fun51', 'fun52']
print(dir(baopy06)) # [... 'c61', 'c62', 'fun61', 'fun62']
print(dir(baopy08)) # [... 'c81', 'c82', 'fun81', 'fun82']
print(dir(baopy09)) # NameError: name 'baopy09' is not defined
以這種方式導入的模塊,在引用時不需要 “包名.” 這個前綴。
五、 __ name__ 和 __ main__
模塊被導入後,系統將它轉化成“模塊對象”,並且還會爲模塊對象缺省添加上一些數據成員。例如:
E:/testpy/py06.py 的內容爲:
class c06:pass
import sys
sys.path.append('E:\\testpy')
import py06
print(dir(py06))
# 顯示:
# ['__builtins__', '__cached__', '__doc__', '__file__',
# '__loader__', '__name__', '__package__', '__spec__', 'c06']
模塊對象中有一個名爲“ __ name__”的數據成員比較常用。當模塊被直接執行時,系統將“模塊對象”的 __ name__值置爲“ __ main__”,當模塊被導入後再直接執行時模塊的 __ name__值置爲“模塊名”。例如:
E:/testpy/py06.py 的內容爲:
class c06:pass; print('py06 __name__:',__name__)
import sys
sys.path.append('E:\\testpy')
import py06 # py06 __name__: py06
print('my __name__:',__name__) # my __name__: __main__
在實際編程中,經常通過 name 的值來判斷一個模塊是否處在被導入中,以此來避免一些語句在導入時被執行。例如:
if __name__ == '__main__': # 噹噹前模塊被導入時,以下這些語句不會被執行
x = 100
y = 200
z = 300
———————————————— 本篇完 ————————————————
看完之後,麻煩您順手點擊下方 “點贊” 兩個字給我點個贊吧 ^-^ , 謝謝您了。
如果您還能像我小學一年級班主任好老師那樣,給我隨心寫上幾句表揚或批評的話語,那真是感激不盡!
在我人生的道路上,有了您的鼓勵和指導,我一定成長快快。