天天看點

Python關于import的實驗(8)__init__.py檔案内部代碼的執行以及内部的導入和内部的變量

Python官方文檔參考連結: 正常包

Python 定義了兩種類型的包,正常包 和 命名空間包。 正常包是傳統的包類型,它們在 Python 3.2 及之前就已存在。 正常包通常以一個包含 __init__.py 檔案的目錄形式實作。 當一個正常包被導入時,這個 __init__.py 檔案會隐式地被執行,它所定義的對象會被綁定到該包命名空間中的名稱。__init__.py 檔案可以包含與任何其他子產品中所包含的 Python 代碼相似的代碼,Python 将在子產品被導入時為其添加額外的屬性。 例如,以下檔案系統布局定義了一個最高層級的 parent 包和三個子包. 導入 parent.one 将隐式地執行 parent/__init__.py 和 parent/one/__init__.py。 後續導入 parent.two 或 parent.three 則将分别執行 parent/two/__init__.py 和 parent/three/__init__.py。

Python關于import的實驗(8)__init__.py檔案内部代碼的執行以及内部的導入和内部的變量
Python關于import的實驗(8)__init__.py檔案内部代碼的執行以及内部的導入和内部的變量

parent\__init__.py:

print("導入parent包...内部已經導入random庫")
str_parent = r"我是parent\__init__.py裡的字元串..."
import random
           

parent\two\__init__.py:

print("導入parent/two包...内部已經導入time庫")
str_parent_two = r"我是parent\two\__init__.py裡的字元串..."
import time
           

parent\three\__init__.py:

print("導入parent/three包...内部已經導入jieba庫")
str_parent_three = r"我是parent\three\__init__.py裡的字元串..."
import jieba
           

parent\one\__init__.py:

print("導入parent/one包...内部已經導入hashlib庫")
str_parent_one = r"我是parent\one\__init__.py裡的字元串..."
import hashlib
           

cmd控制台下的操作:

Windows PowerShell
版權所有 (C) Microsoft Corporation。保留所有權利。

嘗試新的跨平台 PowerShell https://aka.ms/pscore6

PS C:\Users\chenxuqi\Desktop\建立檔案夾\測試包> python
Type "help", "copyright", "credits" or "license" for more information.
>>> import parent
導入parent包...内部已經導入random庫
>>> parent.str_parent
'我是parent\\__init__.py裡的字元串...'
>>> random
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'random' is not defined
>>> parent.random
<module 'random' from 'D:\\Python\\Python37\\lib\\random.py'>
>>> parent.random.randint(2,7)
7
>>> parent.random.randint(2,7)
7
>>> parent.random.randint(2,7)
7
>>> parent.random.randint(2,7)
7
>>> parent.random.randint(2,7)
7
>>> parent.random.randint(2,9)
5
>>> parent.random.randint(2,9)
2
>>> parent.random.randint(2,9)
3
>>> parent.random.randint(2,9)
8
>>> parent.random.randint(2,7)
5
>>> parent.random.randint(2,7)
2
>>> parent.random.randint(2,7)
5
>>> parent.random.randint(2,7)
6
>>> import parent.two
導入parent/two包...内部已經導入time庫
>>> parent.two.str_parent_two
'我是parent\\two\\__init__.py裡的字元串...'
>>> parent.two.time
<module 'time' (built-in)>
>>> parent.two.time.time()
1605883430.647523
>>> time
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'time' is not defined
>>> from parent.two import time
>>> time
<module 'time' (built-in)>
>>> now = time.time()
>>> print(time.ctime(now))
Fri Nov 20 22:46:45 2020
>>> import parent.three
導入parent/three包...内部已經導入jieba庫
>>> import parent.three as three
>>> three.str_parent_three
'我是parent\\three\\__init__.py裡的字元串...'
>>> three.jieba
<module 'jieba' from 'D:\\Python\\Python37\\lib\\site-packages\\jieba\\__init__.py'> 
>>> jieba.lcut("全國計算機等級考試Python科目")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'jieba' is not defined
>>> three.jieba.lcut("全國計算機等級考試Python科目")
Building prefix dict from the default dictionary ...
Dumping model to file cache C:\Users\chenxuqi\AppData\Local\Temp\jieba.cache
Loading model cost 0.857 seconds.
Prefix dict has been built successfully.
['全國', '計算機', '等級', '考試', 'Python', '科目']
>>> from parent.one import str_parent_one
導入parent/one包...内部已經導入hashlib庫
>>> str_parent_one
'我是parent\\one\\__init__.py裡的字元串...'
>>> from parent.one import hashlib as hsb
>>> hsb
<module 'hashlib' from 'D:\\Python\\Python37\\lib\\hashlib.py'>
>>> hsb.md5("尹增寶愛聽古風音樂".encode("utf8")).hexdigest()
'075649873523f1e621d4b33f69b60ebb'
>>>
>>> hsb.md5("林祖泉".encode("utf8")).hexdigest()
'738974139c96e7c1b174e1f886ffb641'
>>>
>>> 
           

導入一個包之後,無法通路其子包,除非其子包有__init__.py檔案,而且該檔案已經被執行過一次,那麼該包就會有其該子包的屬性,否則會報錯,比如:AttributeError: module 'parent' has no attribute 'three'

修改./__init__.py檔案:

print("導入parent包...内部已經導入random庫")
str_parent = r"我是parent\__init__.py裡的字元串..."
import random
import parent.one as yi
from parent import two
# import parent.three
           

cmd控制台下的操作如下:

Windows PowerShell
版權所有 (C) Microsoft Corporation。保留所有權利。

嘗試新的跨平台 PowerShell https://aka.ms/pscore6

PS C:\Users\chenxuqi\Desktop\建立檔案夾\測試包> python
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul  8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> parent
Traceback (most recent call last):     
  File "<stdin>", line 1, in <module>  
NameError: name 'parent' is not defined
>>> import parent
導入parent包...内部已經導入random庫
導入parent/one包...内部已經導入hashlib庫
導入parent/two包...内部已經導入time庫   
>>> parent
<module 'parent' from 'C:\\Users\\chenxuqi\\Desktop\\建立檔案夾\\測試包\\parent\\__init__.py'>
>>> parent.one
<module 'parent.one' from 'C:\\Users\\chenxuqi\\Desktop\\建立檔案夾\\測試包\\parent\\one\\__init__.py'>
>>> parent.yi
<module 'parent.one' from 'C:\\Users\\chenxuqi\\Desktop\\建立檔案夾\\測試包\\parent\\one\\__init__.py'>
>>> parent.two
<module 'parent.two' from 'C:\\Users\\chenxuqi\\Desktop\\建立檔案夾\\測試包\\parent\\two\\__init__.py'>
>>> yi
Traceback (most recent call last):   
  File "<stdin>", line 1, in <module>
NameError: name 'yi' is not defined  
>>> two
Traceback (most recent call last):   
  File "<stdin>", line 1, in <module>
NameError: name 'two' is not defined 
>>> one
Traceback (most recent call last):   
  File "<stdin>", line 1, in <module>
NameError: name 'one' is not defined 
>>> three
Traceback (most recent call last):    
  File "<stdin>", line 1, in <module> 
NameError: name 'three' is not defined
>>> parent.three
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'parent' has no attribute 'three'
>>> import parent.three         
導入parent/three包...内部已經導入jieba庫
>>> parent.three
<module 'parent.three' from 'C:\\Users\\chenxuqi\\Desktop\\建立檔案夾\\測試包\\parent\\three\\__init__.py'>
>>> three
Traceback (most recent call last):    
  File "<stdin>", line 1, in <module> 
NameError: name 'three' is not defined
>>> import parent.three as three
>>> three
<module 'parent.three' from 'C:\\Users\\chenxuqi\\Desktop\\建立檔案夾\\測試包\\parent\\three\\__init__.py'>
>>> 
>>> 
           

實驗源代碼擷取: 源代碼下載下傳連結