from pathlib import Path,PosixPath print(dir()) print(Path) print(PosixPath) 運行結果: ['Path', 'PosixPath',...] <class 'pathlib.Path'> <class 'pathlib.PosixPath'>
Path和PosixPath是pathlib模塊中定義的類,使用 "from .. import .."語句能夠直接映射pathlib模塊中的資源在當前的命名空間。接下來就可使用資源名直接調用,不須要再以"pathlib.Path" 這樣的完整資源層次關係調用。python
from pathlib import Path,PosixPath import pathlib.Path print(dir()) print(Path) print(PosixPath) print(pathlib.Path) 運行結果: Traceback (most recent call last): File "C:/python/1207.py", line 2, in <module> import pathlib.Path ImportError: No module named 'pathlib.Path'; 'pathlib' is not a package
包的簡單概念:
包必須是目錄,且此目錄下有一個__init__.py,好比下面的層級關係:編程
|--包windows
|--__init__.py
|--子模塊.py
|--子模塊
|--子模塊.py函數
包下面能夠有多個嵌套的子模塊,後面會單獨一篇文章介紹包。ui
模塊必須是一個文件夾或者單獨的以py結尾的文件,好比下面的層級關係:
|--os
|--path.pyspa
上面的樹狀文件路徑中os是一個頂級模塊,path是os模塊下的一個子模塊。blog
再看下pathlib的層級關係:
|--pathlib.py
|--class Path(PurePath)
上面的pathlib就是一個單獨的頂級模塊,Path只是這個模塊中的一個類,並非一個模塊,因此import pathlib.Path 直接導入時會拋出 No module named 'pathlib.Path' 異常。內存
若是須要直接導入模塊裏面的資源就必須使用 from 模塊 import 資源名 的格式,下一個例子就會介紹這種格式。資源
from pathlib import * #導入模塊下的全部"公共"資源 print(dir()) print(Path.cwd()) 運行結果: ['Path', 'PosixPath', 'PurePath', 'PurePosixPath', 'PureWindowsPath', 'WindowsPath', ...]
經過前一個例子的異常,咱們知道import 沒法直接導入頂級模塊或子模塊中的資源(類,方法,屬性),使用 from .. import * 語句(第一種方法)就會將指定模塊下的全部資源導入,或者指定資源名的格式導入部分資源: from .. import 資源(第二種方法) ,這兩種方法都會將資源同名映射到當前命名空間。
第二種方法相比第一種方法的好處是,只導入須要的資源,其它用不到的資源統統不導入,能夠節省內存,這是一種好的編程習慣,在程序效率上任何微小的提高積累起來都是大的提高。it
本例子中特別強調了 from .. import * 導入的是模塊下的全部」公共「資源,公共資源也就是不以單下劃線(_xx)或者雙下劃線(__yy__)開頭的資源。
from os import path as osp #別名 print(dir()) 運行結果: ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'osp']
在導入子模塊或者資源時也可使用as 語句重命名子,當前命名空間最終保存的就是重命名後的映射。
from os.path import exists print(dir()) if exists('c:/windows'): print('found') else: print('not found') 運行結果: ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'exists'] found
當前例子中使用了 from 包.模塊 import 子模塊 的格式,說明from語句後的模塊能夠是完整層級關係下的模塊(依然有一個找模塊、加載模塊、初始化模塊的過程),也能夠是單獨的模塊,最終當前加入命名空間的依然是子模塊名的映射。
from os.path import exists print(dir()) print(exists) import os print(dir()) print(os.path.exists) print(os.path.__dict__['exists']) 運行結果: ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'exists'] <function exists at 0x000001F7AEDAC268> ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'exists', 'os'] <function exists at 0x000001F7AEDAC268> <function exists at 0x000001F7AEDAC268>
當前例子中前後使用不一樣的導入方式,導入path模塊的exists函數,最終比較內存地址時,按道理說先後調用的方式是不同的,卻發現內存地址是一致的。
模塊加載機制中可能有一種在當前環境中防止重複導入模塊的機制,下一篇文章再作介紹。
1. from 語句須要指定模塊,模塊能夠是單獨的頂級模塊,也能夠是層級關係下的子模塊,加載並初始化該模塊
2. import 語句後指定的是該模塊的資源(類,方法,函數),或者導入該模塊下的子模塊。
先查找導入的模塊是具備該名稱的屬性 -->若是沒有,就嘗試導入爲該名稱的子模塊 --> 若是尚未找到,就拋出ImportError異常。下一篇文章也會舉例介紹該模塊搜索順序。
若是該名稱後有as語句,則關聯as語句後的名稱到當前名詞空間