Python基礎手冊27——模塊

一、模塊

1、模塊和導入

當程序代碼量變得相當大、邏輯結構變得非常復雜的時候,我們最好把代碼按照邏輯和功能劃分成一些有組織的代碼塊,并將其保存到一個個獨立的文件當中。這些文件可以包含可執行代碼、函數、類或者這些東西的組合,這些自我包含并且有組織的代碼塊就是模塊( module )。模塊是最高級別的 Python 代碼組織單元。

模塊往往對應于物理機上的 Python 文件(或者是用外部語言如C、Java或C#編寫而成的擴展)。當你創建了一個 Python 源文件,其對應的模塊的名字就是不帶 .py 后綴的文件名。一個模塊(Python程序文件)創建之后, 你可以從另一個文件中使用 import 語句導入這個模塊來使用,從而實現代碼的重用。這個把其他模塊附加到你的代碼中的操作叫做導入( import )。導入其他模塊之后就可以使用導入的模塊中定義的變量名。


2、模塊的作用

代碼重用

因為模塊對應于 Python 文件,所以模塊中的代碼可以永久保存。你可以按照需要在代碼中任意次數的使用導入的模塊中定義的變量名(函數、類等),甚至可以重新導入模塊。除了作為最高級別的 Python 代碼組織單元,模塊(以及 模塊包)也是 Python 中程序代碼重用的最高層次。

系統命名空間的劃分

模塊還是定義變量名的空間,其內部定義的變量名作為模塊的屬性,可以通過導入被多個外部的文件中的代碼引用。

模塊將變量名封裝進了自己的命名空間,這一點對避免變量名的沖突很有幫助。所有的一切都存在于 ”模塊“ 中,可執行的代碼以及創建的對象都毫無疑問的封裝在模塊之中。正式由于這一點,模塊是組織系統組件的天然工具。

實現共享服務和數據

從操作的角度來看,模塊對實現跨系統共享的組件是很方便的,只需要在不同的文件中導入相同的模塊即可。


3、Python 的程序架構

一個 Python 程序通常都不僅僅涉及一個文件,一般都會采用多文件系統的形式。即使編寫單個文件,幾乎也一定會導入標準庫模塊或者使用到其他人已經寫好的外部文件。

一般來講一個完整的程序由啟動運行的腳本文件以及零個或多個作為支持(用作導入)的文件組成。

在 Python 中,頂層文件包含了程序的主要的控制流程:這就是你需要運行來啟動程序的文件。作為模塊被導入的文件通常在運行時不需要直接做任何事,它提供了頂層文件運行所需要的各種組件(普通變量、函數、類等)。頂層文件使用了在模塊文件中定義的組件,而這些模塊使用了其他模塊所定義的組件。

在 Python 中,一個文件導入了一個模塊來獲得這個模塊中定義的變量的訪問權,這些變量被認作是這個模塊的屬性。導入的概念在 Python 之中貫穿始末。任何文件都能從任何其他文件中導入其變量,導入鏈要多深就有多深。

4、標準庫模塊

Python 自帶了很多實用的模塊,稱為標準鏈接庫。這個集合體大約有200多個模塊,包含與平臺不相關(不依賴于具體的系統,可以在任何系統上以同樣的方式調用,也就是說這些標準庫模塊是跨平臺的)的常見程序設計任務:操作系統接口、對象永久保存、文字模式匹配、網絡和 internet 腳本、GUI 建構等。

這些工具都不是 Python 語言的組成部分,但是,你可以在任何安裝了 Python 的環境中,導入適當的模塊來使用。因為這些都是標準庫模,所以他們一定可以用,而且在執行 Python 的絕大數平臺上都可以運行。


二、模塊的導入

模塊中的代碼會在首次導入時執行,首先建立空的模塊對象,然后按照從頭到尾的順序,逐一執行該模塊內的語句。頂層(不在def或class之內)的賦值語句(例如,=、def 和 class等)生成的變量會成為模塊對象的屬性,這些變量名會存儲在模塊的命名空間內。模塊的命名空間能通過屬性 __dict__ 或內建函數 dir() 獲取。

1、模塊文件的命名

任何以 “.py” 為后綴名的 Python 文件都會被自動認為是 Python 模塊,一般來說,Python 文件怎么命名都可以,但是如果打算將其作為模塊導入,文件必須以 ”.py“ 結尾。
對于會執行但不會被導入的頂層文件而言,.py 后綴從技術上來說是可有可無的,但是每次都加上去,可以確保文件類型更醒目,并使其以后可以被導入到任何文件中。

因為模塊名在 Python 程序中會變成變量名(沒有.py)。因此Python文件應該遵循普通變量名的命名規則。事實上,包導入中所用的模塊的文件名和目錄名都必須遵循變量名規則。


2、導入模塊的步驟

在Python中,導入并不是把一個文件文本插入另一個文件中。導入其實是運行時的運算,程序第一次導入指定文件時,會執行三個步驟。
1、搜索找到模塊文件。
2、編譯成字節碼(需要時)。
3、執行模塊的代碼來創建其所定義的對象,定義 import 語句所在文件的作用域的局部命名空間中的一個或多個變量名。

這三個步驟只在模塊第一次導入時才會執行。在這之后,導入相同模塊時,會跳過這三個步驟,而只是提取內存中已加載的模塊對象。這是有意而為之的,因為該操作開銷較大。如果你在模塊已加載后還需要再次導入(例如,為了支持終端用戶的定制),你就得通過調用 reload() 強制導入模塊。

從技術上講,Python 把載入的模塊存儲到一個名為 sys.modules 的表中,并在導入操作的開始檢查該表。如果模塊不存在,將會自動執行上面的三個步驟。

搜索

Python 會遍歷模塊搜索路徑,查找 import 語句所引用的模塊文件。在導入者文件中,只能列出要導入的模塊文件的簡單名稱,路徑和后綴是刻意省略掉的。

當一個模塊被導入時,Python 會把程序內部的模塊名映射到外部物理環境中的文件名,也就是將模塊搜索路徑中的目錄路徑添加在模塊名前邊,并在模塊名的后邊添加 .py 或其他后綴名。

編譯

找到模塊文件后,Python 會查找對應的 .pyc 字節碼文件。如果沒有字節碼文件,Python 會將模塊文件編譯成字節碼文件。如果找到對應的字節碼文件,Python 會檢查文件的時間戳,如果發現字節碼文件比模塊文件舊(例如,如果你修改過源文件),就會重新編譯模塊文件生成新的字節碼文件。如果字節碼文件不比對應的 .py 源代碼文件舊,就會跳過源代碼到字節碼的編譯步驟。

如果 Python 在搜索路徑上只發現了字節碼文件,而沒有源代碼,就會直接加載字節碼文件(這意味著你可以把一個程序只作為字節碼文件發布,而避免發送源代碼)。換句話說,直接使用字節碼文件跳過編譯步驟,會提高程序的啟動提速。

通常不會看見程序頂層文件的 .pyc 字節碼文件,除非這個文件也別其他文件導入:只有被導入的文件才會在機器上留下 .pyc 。頂層文件的字節碼是在內部使用后就丟棄了,被導入文件的字節碼則保存在文件中從而可以提高之后導入的速度。

頂層文件通常是設計成直接執行,而不是被導入的。

運行

import 操作的最后步驟是執行模塊的字節碼。文件中所有語句會從頭到尾依次執行,而此步驟中任何對變量名的賦值運算,都會產生模塊文件的屬性。因此,這個執行步驟會生成模塊代碼所定義的所有工具。

因為最后的導入步驟實際上是執行文件的程序代碼,如果模塊文件中任何頂層代碼確實做什么實際的工作,你就會在導入時看見其結果。


3、import 語句

常見的 import 導入語句可以分為兩種:單獨的 import 語句用來導入模塊名;帶有
from 的 import 語句用來導入模塊中的變量名,同時可以使用 * 號導入模塊中的所有變量。在以上兩種語句中,我們都可以使用 as 語句為導入的模塊或變量指定別名。當語句包含多個子句(以逗號分隔)時,為每個子句分別執行模塊導入的三個步驟,就像子句已被分隔為單獨的 import 語句一樣。

如果導入的模塊被成功檢索到,它將通過以下三種方式之一綁定到本地命名空間:

  • 如果模塊名后面是 as,則 as 之后的變量名將在本地命名空間中綁定為對導入的模塊對象的引用。
  • 如果未指定其他名稱,并且正在導入的模塊是頂級模塊(),則模塊的名稱將在本地命名空間中綁定為對導入模塊對象的引用。
  • 如果正在導入的模塊不是頂級模塊,則包含該模塊的頂級包的名稱在本地命名空間中被綁定為對頂級包的引用。導入的模塊必須使用其完全限定名稱而不能直接訪問。包的概念會在后續章節介紹。

from 形式會多一些復雜的過程:

  1. 找到 from 子句中指定的模塊,如果需要,加載和初始化它;
  2. 對于 import 子句中指定的每個標識符:
    a. 檢查導入的模塊是否具有該名稱的屬性;
    b. 如果沒有,請嘗試導入具有該名稱的子模塊,然后再次檢查導入的模塊的該屬性;
    c. 如果未找到該屬性,則引發 ImportError;
    d. 如果找到該名稱的屬性,對該屬性的引用存儲在本地命名空間中,使用 as 子句中的名稱(如果存在),否則使用屬性名稱;

如果在 from 語句中 import 后面的標識符列表被替換為星號(*),則模塊中定義的所有公共名稱都在 import 語句所在的作用域的本地命名空間中綁定。

(1)import 形式

import 語句將模塊導入文件中:
import module_name

import 是可執行語句,就像 def 一樣,它是隱性的賦值語句。當 Python 執行到這個語句時,會將導入生成的模塊對象賦值給 import 語句后面的模塊名,而模塊文件頂層對任意類型賦值了的變量名,都會產生為模塊對象的屬性。

一旦導入完成,一個模塊的屬性(函數和變量)可以通過熟悉的 (. )句點屬性標識法訪問。
module.function()
module.variable

import 語句組合兩個操作;它搜索指定的模塊并根據需要執行模塊以得到模塊對象,然后將模塊對象綁定到本地作用域中的模塊名。

import 語句的搜索操作被定義為:使用適當的參數調用 __import__() 函數。直接調用 __import__() 只執行模塊搜索,如果找到,則執行模塊創建操作,并返回模塊對象。如果找不到指定的模塊,則會引發 ImportError。雖然可能會伴隨著某些其他的操作,例如導入父包以及更新各種緩存(包括sys.modules),但只有 import 語句會執行名稱綁定操作。

屬性名的點號運算

在 Python 之中,可以使用點號運算語法 object.attribute 獲取任意的 object 的attribute 屬性。

點號運算符其實就是表達式,傳回和對象相配的屬性名的值。當使用點號運算符來讀取變量名時,就把明確的對象提供給 Python , LEGB 規則只適用于無點號運算的純變量名。

簡單變量名

X 是指在當前作用域內搜索變量名 X(遵循LEGB規則)

點號運算

X,Y 是指在當前范圍內搜索 X,然后搜索對象 X 之中的屬性 Y(而非在作用域里)。

多層點號運算

X,Y,Z 指的是在當前范圍內搜索 X,然后搜索對象 X 之中的屬性 Y,然后在對象X.Y 中搜索屬性 Z 。

通用性

點號運算可用于任何具有屬性的對象:模塊、類、C 擴展類型等。


(2)from - import 形式

使用 from-import 語句可以將模塊的屬性導入到當前作用域,并綁定到指定的變量名。
from module import name1[, name2[,... nameN]]

和 import 一樣,from - import 語句也是可執行的隱性賦值語句。import 將導入的模塊對象賦值給一個模塊名。而 from - import 將模塊中的一個或多個變量(也就是生成的模塊對象的一個或多個屬性)綁定到當前文件中 import 語句指定的變量名。因為 from 會把模塊中定義的變量名復制到另一個文件的作用域中,所以它就可以讓我們直接在另一個文件中直接使用從模塊中導入的變量名,而不需要通過模塊名。(例如:variate)

from 的第一步驟也是普通的導入操作。因此,from 總是會把整個模塊導入到內存中(如果還沒被導入的話),無論是從這個文件中復制出多少變量名。只加載模塊文件的一部分(例如,一個函數)是不可能的。但是因為模塊在 Python 之中是字節碼而不是機器碼,通常可以忽略效率的問題。

from 語句潛在的陷阱

因為 from 語句會讓變量位置更隱秘和模糊,所以 form 語句可能會破壞命名空間。如果使用 from 導入變量,而那些變量碰巧和作用域中現有變量同名,變量就會被悄悄地覆蓋掉。使用簡單的 import 語句就不會有這種問題,因為你一定得通過模塊名才能獲取其屬性(變量名)。不過使用 from 時,只要你了解并預料到可能發生這種事,在實際情況下這就不是一個大問題了,尤其當你明確列出導入的變量名時(例如,from moudle import a, b, c)。

和 reload 調用同時使用時,from 語句有比較嚴重的問題,因為導入的變量名可能引用之前導入的對象。

簡單模塊一般傾向于使用 import,而不是 from。多數的 from 語句是用于明確列舉出想要的變量,而且限制在每個文件中只用一次 from * 形式。當你必須使用兩個不同模塊內定義的相同的變量名時,才真的必須使用 import,這種情況下不能用 from(當然你可以在 from 語句中使用 as 語句來個規避變量名沖突的問題)。


(3)from - import * 形式

從一個模塊導入許多變量名時,import 行會越來越長,直到自動換行,而且我們需要使用反斜杠字符 \ 讓一條語句橫跨多行 。

from module import name1, name2, name3, name4,\
   name5, name6, name7

你可以選擇使用多行的 from-import 語句:

from module import name1, name2, name3, name4
from module import name5, name6, name7

在 from 語句的 import 子句中,當我們使用 * 時,會取得模塊頂層所有賦值的變量名的拷貝。從根本上來說,這就是把一個模塊的命名空間融入另一個模塊之中;同樣地,實際效果就是可以讓我們少輸入一些代碼。from * 語句形式只能用在一個模塊文件的頂部,嘗試在類或函數定義中使用它將引發 SyntaxError。


核心風格: 限制使用 " from - import * "

在實踐中, 我們認為 "from - import *" 不是良好的編程風格,因為它"污染"當前名稱空間,讓變量名難以理解。而且很可能覆蓋當前名稱空間中現有的名字,尤其是在導入一個以上的模塊時。事實上,from * 形式會把一個命名空間融入到另一個,所以會使得模塊的命名空間的分割特性失效。

如果某個模塊有很多要經常訪問的變量或者模塊的名字很長,這也不失為一個方便的好辦法。我們只在兩種場合下建議使用這樣的方法,一個場合是:要使用的目標模塊中的屬性非常多,反復鍵入模塊名很不方便,例如 Tkinter (Python/Tk) 和 NumPy (Numeric Python) 模塊,可能還有 socket 模塊。另一個場合是在交互解釋器下,因為這樣可以減少輸入次數。

一般情況下,我們不提倡使用不再流行的 from module import * 語句 。真正的 Python 程序員應該使用 Python 的標準分組機制(圓括號)來創建更合理更明確的多行導入語句。

最小化 from * 的破壞:_x 和 __all__

把下劃線放在變量名前面(例如,_x),可以防止客戶端使用 from * 語句導入模塊名時,把其中的那些變量名復制出去。這其實是為了對命名空間的破壞最小化而已。下劃線不是私有變量的聲明:你還是可以使用其他導入形式看見并修改這類變量名。

此外,你也可以在模塊頂層把變量名的字符串列表賦值給變量名 __all__ ,以達到類似于 _x 命名慣例的隱藏效果。

使用此功能時,from * 語句只會把列在 __all__ 列表中的這些變量名賦值出來。事實上這和 x 慣例相反 __all時指出要復制的變量名,而_x 是指出不被復制的變量名。Python 會先尋找模塊內的 __all_ 列表;如果沒有定義的話,from * 就會復制出開頭沒有單下劃線的所有變量名。

就像 _x 慣例一樣,__all__ 列表只對 from * 語句這種形式有效,它并不是私有聲明。


(4)擴展的導入語句(as)

有時候你導入的模塊名或是模塊屬性名稱已經在你的程序中使用了,或者你不想使用導入的名字,可能是它太長不便輸入什么的。 這已經成為 Python 程序員的一個普遍需求:使用自己想要的名字替換模塊的原始名稱。使用擴展的 as 子句,你就可以在導入的同時指定局部綁定名稱。

import 語句和 from 語句都可以擴展,讓模塊可以在腳本中給予不同的變量名。

import modulename as name
相當于:
import modulename
name = modulename
del modulename

from modulename import attrname as name
相當于:
from modulename import attrname
name = attrname
del attrname

這個擴展功能很常用,替代變量名較長的變量提供簡短一些的同義詞,而且當已在腳本中使用一個變量名使得執行普通 import 語句會被覆蓋時,使用 as,就可避免變量名沖突。


4、模塊重載

在同一個進程中模塊只在第一次導入時,加載和執行該模塊的代碼。之后的導入只會使用已加載的模塊對象,而不會重載或重新執行文件的代碼。要強制使模塊重新載入并重新運行,可以使用 reload() 函數。

reload()

reload() 函數位于Python中的 imp 模塊內,使用前必須先導入。它會強制已加載的模塊的代碼重新載入并重新執行。因為 reload() 期望得到的是對象,在重載之前,模塊一定是已經預先成功導入了。

重新執行模塊文件的代碼會覆蓋其現有的命名空間。重載會影響所有使用 import 導入模塊的程序,因為使用 import 的程序需要通過點號運算符取出屬性,在重載后,使用的模塊對象變成了新的值。重載只會對重載后使用 from 語句導入模塊的程序造成影響。之前使用 from 來讀取屬性的客戶端并不會受到重載的影響,那些程序引用的依然是重載前所取出的舊對象。

reload() 函數使得可以修改模塊程序的一些代碼,而無須停止整個程序。因此,利用reload() ,可以立即看到對模塊的修改效果。重載無法用于每種情況,但是能用時,可縮短開發的流程。一般的用法是:導入一個模塊,在文本編輯器內修改其源代碼,然后將其重載。當調用 reload() 時,Python 會重讀模塊文件的源代碼,重新執行其頂層語句。

因為 Python 是解釋性的(或多或少),其實已經避免了類似 C 語言程序執行時所需的編譯連接步驟:在執行程序導入時,模塊會動態加載。重載進一步的提供了性能優勢,讓你可以修改執行中的程序的一部分,而不需要中止。注意:reload() 當前只能用在Python 編寫的模塊;用 C 這類語言編寫的編譯后的擴展模塊也可在執行中動態加載,但無法重載。


《Python基礎手冊》系列:

Python基礎手冊 1 —— Python語言介紹
Python基礎手冊 2 —— Python 環境搭建(Linux)
Python基礎手冊 3 —— Python解釋器
Python基礎手冊 4 —— 文本結構
Python基礎手冊 5 —— 標識符和關鍵字
Python基礎手冊 6 —— 操作符
Python基礎手冊 7 —— 內建函數
Python基礎手冊 8 —— Python對象
Python基礎手冊 9 —— 數字類型
Python基礎手冊10 —— 序列(字符串)
Python基礎手冊11 —— 序列(元組&列表)
Python基礎手冊12 —— 序列(類型操作)
Python基礎手冊13 —— 映射(字典)
Python基礎手冊14 —— 集合
Python基礎手冊15 —— 解析
Python基礎手冊16 —— 文件
Python基礎手冊17 —— 簡單語句
Python基礎手冊18 —— 復合語句(流程控制語句)
Python基礎手冊19 —— 迭代器
Python基礎手冊20 —— 生成器
Python基礎手冊21 —— 函數的定義
Python基礎手冊22 —— 函數的參數
Python基礎手冊23 —— 函數的調用
Python基礎手冊24 —— 函數中變量的作用域
Python基礎手冊25 —— 裝飾器
Python基礎手冊26 —— 錯誤 & 異常
Python基礎手冊27 —— 模塊
Python基礎手冊28 —— 模塊的高級概念
Python基礎手冊29 —— 包

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,345評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,494評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,283評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,953評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,714評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,410評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,940評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,776評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,210評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,654評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容

  • Python 面向對象Python從設計之初就已經是一門面向對象的語言,正因為如此,在Python中創建一個類和對...
    順毛閱讀 4,231評論 4 16
  • 定義類并創建實例 在Python中,類通過 class 關鍵字定義。以 Person 為例,定義一個Person類...
    績重KF閱讀 3,959評論 0 13
  • 有些人都會對你的點子和想法表現很冷淡,因為他們并不想你成功,不想你賺到錢,因為他們不想你比他們厲害。這就是人性...
    謝燁wa閱讀 665評論 0 4
  • 《溫飽思淫欲》 他總是這樣,飯飽思淫欲,每天中午,一吃過飯,他都摸著肚子打著嗝,用他肥膩膩的手伸進抽屜翻找...
    即墨柯_c046閱讀 464評論 0 0
  • 當最后一顆星星離去 我早已忘記了你的容顏 當整個星空陷入無際的黑暗 是否曾想起 多年之前 星空燦爛 多年之前 我們...
    零落霜結閱讀 232評論 0 0