樂趣Python——函數(shù)與模塊:代碼界的樂高積木

嘿矢渊,小伙伴們,今天我們要進入代碼界的樂高世界——那就是Python的函數(shù)與模塊枉证!想象一下矮男,用樂高積木可以建造城堡、汽車室谚、甚至太空船毡鉴,而在Python的世界里,函數(shù)就像是你的小秘舞萄,幫你傳話眨补,完成任務(wù)。如果你想要效率翻倍倒脓,讓函數(shù)來幫忙吧撑螺!

函數(shù):你來我往的傳話游戲:

"在Python的世界里,函數(shù)就像是你的小秘崎弃,幫你傳話甘晤,完成任務(wù)。想要效率翻倍饲做?讓函數(shù)來幫忙线婚!"

1. 定義一個函數(shù)

專業(yè)理論

在Python中,函數(shù)是用來封裝一段可執(zhí)行的代碼塊盆均,這樣你就可以在程序的多個地方調(diào)用它塞弊,而不必重復(fù)寫相同的代碼。

類比理解

想象一下,你有一個超級能力:每當(dāng)你拍拍手游沿,你的房間就會自動整理干凈饰抒。這個拍拍手就像是一個“函數(shù)”,你只需要做一個動作(調(diào)用函數(shù))诀黍,房間就整理干凈了袋坑。

示例代碼

# 定義一個函數(shù)
def clean_room():
    print("您的房間已經(jīng)打掃干凈!")

# 調(diào)用函數(shù)
clean_room()

2. 函數(shù)調(diào)用

調(diào)用函數(shù)就像是按下遙控器的按鈕眯勾,執(zhí)行一個預(yù)設(shè)好的操作枣宫。

示例代碼

# 定義一個函數(shù),告訴大家今天的天氣
def tell_weather():
    print("今天是晴天吃环!")

# 調(diào)用函數(shù)
tell_weather()

# 可以多次調(diào)用也颤,不用寫重復(fù)代碼,只需寫一次代碼模叙,封裝在函數(shù)中
tell_weather()

3. 參數(shù)傳遞

專業(yè)理論

當(dāng)你調(diào)用函數(shù)時歇拆,可以向它傳遞信息,這就是參數(shù)范咨。根據(jù)參數(shù)是可更改(mutable)還是不可更改(immutable)對象故觅,函數(shù)內(nèi)部對這些參數(shù)的修改可能會影響到函數(shù)外部的原始對象。

類比理解

想象你把一個秘密告訴你的朋友渠啊,如果這個秘密(參數(shù))是“不可更改的”输吏,即使你的朋友想要修改它,原始的秘密也不會變替蛉。但如果是“可更改的”贯溅,你的朋友就可能會把這個秘密變成一個全新的版本。

示例代碼

# 不可更改(immutable)對象示例
def change_number(a):
    a = 5

number = 10
change_number(number)
print(number)  # 結(jié)果仍然是10

# 可更改(mutable)對象示例
def change_list(my_list):
    my_list.append(4)

numbers = [1, 2, 3]
change_list(numbers)
print(numbers)  # 結(jié)果是[1, 2, 3, 4]

4. 調(diào)用函數(shù)時可使用的正式參數(shù)類型

必需參數(shù)

這就像是游戲里的必須完成的任務(wù)躲查,沒有它們你就無法進行下去它浅。

def say_hello(name):
    print(f"Hello, {name}!")

say_hello("Alice")

代碼定義了一個名為say_hello的函數(shù),該函數(shù)接受一個參數(shù)name镣煮。在函數(shù)中姐霍,使用print語句輸出了"Hello, {name}!",其中{name}會被傳遞進來的參數(shù)替換典唇。
然后通過調(diào)用say_hello("Alice")函數(shù)镊折,執(zhí)行了該函數(shù),并傳遞了一個名為"Alice"的參數(shù)介衔。
因此恨胚,執(zhí)行此代碼后,您將在屏幕上看到以下輸出:

Hello, Alice!

關(guān)鍵字參數(shù)

就像是你在命令你的小機器人時指定了具體的執(zhí)行動作炎咖。

def describe_pet(animal, name):
    print(f"我養(yǎng)了一只{animal}赃泡,名字叫{name}寒波。")

describe_pet(animal="倉鼠", name="哈利")

這段代碼定義了一個名為describe_pet的函數(shù),該函數(shù)接受兩個參數(shù) animalname升熊。在函數(shù)中影所,使用print語句輸出了"我養(yǎng)了一只{animal},名字叫{name}僚碎。",并使用傳遞進來的參數(shù)進行替換阴幌。
然后通過調(diào)用 describe_pet(animal="倉鼠", name="哈利") 函數(shù)勺阐,執(zhí)行了該函數(shù),并傳遞了兩個參數(shù)矛双,animal 參數(shù)的值為 "倉鼠"渊抽,name 參數(shù)的值為 "哈利"。
執(zhí)行此代碼后议忽,將在屏幕上看到以下輸出:

我養(yǎng)了一只倉鼠懒闷,名字叫哈利。

默認(rèn)參數(shù)

就像每次點咖啡栈幸,默認(rèn)就是拿鐵愤估。如果指定了就是喝別的咖啡,比如:

def make_coffee(type="latte"):
    print(f"制作一杯{type}咖啡速址。")

make_coffee()  # 默認(rèn)是拿鐵
make_coffee("冰美式")  # 指定為冰美式

這段代碼定義了一個名為make_coffee的函數(shù)玩焰,它有一個名為type的參數(shù),默認(rèn)值為"latte"芍锚。在函數(shù)中昔园,使用print語句輸出了"制作一杯{type}咖啡。"并炮,并使用傳遞進來的參數(shù)進行替換默刚。

然后通過調(diào)用 make_coffee() 函數(shù),函數(shù)會使用默認(rèn)值"latte"來制作一杯咖啡逃魄。執(zhí)行此代碼后荤西,您將在屏幕上看到以下輸出:

制作一杯拿鐵咖啡。

接下來嗅钻,通過調(diào)用 make_coffee("冰美式") 函數(shù)皂冰,函數(shù)會使用指定值"冰美式"來制作一杯咖啡。執(zhí)行此代碼后养篓,您將在屏幕上看到以下輸出:

制作一杯冰美式秃流。

不定長參數(shù)

就好比你在制作披薩,不管你想放多少配料進去都行柳弄。

def make_pizza(*toppings):
    print("正在制作披薩舶胀,加入以下配料:")
    for topping in toppings:
        print(f"- {topping}")

make_pizza("意式辣香腸")
make_pizza("蘑菇", "青椒", "額外芝士")

這段代碼定義了一個名為make_pizza的函數(shù)概说,它使用了一個特殊的參數(shù) *toppings,這意味著可以接受任意數(shù)量的參數(shù)嚣伐,并將它們放入一個元組中糖赔。在函數(shù)中,使用print語句輸出"正在制作披薩轩端,加入以下配料:"放典,然后使用循環(huán)遍歷元組中的每個配料,并使用print語句以"- {topping}"的格式打印每個配料基茵。

然后通過調(diào)用 make_pizza("意式辣香腸") 函數(shù)奋构,函數(shù)會制作一張只有"意式辣香腸"的披薩。執(zhí)行此代碼后拱层,您將在屏幕上看到以下輸出:

正在制作披薩弥臼,加入以下配料:
- 意式辣香腸

接下來,通過調(diào)用 make_pizza("蘑菇", "青椒", "額外芝士") 函數(shù)根灯,函數(shù)會制作一張有"蘑菇"径缅、"青椒"和"額外芝士"的披薩。執(zhí)行此代碼后烙肺,您將在屏幕上看到以下輸出:

正在制作披薩纳猪,加入以下配料:
- 蘑菇
- 青椒
- 額外芝士

5. 匿名函數(shù)

專業(yè)理論

匿名函數(shù),也稱為lambda函數(shù)茬高,是一種簡單的兆旬、在一行內(nèi)定義的函數(shù)。

類比理解

想象你在快速寫一個便條怎栽,告訴別人怎么做一件事丽猬,而不需要正式地寫一封信。

示例代碼

sum = lambda a, b: a + b

print(sum(5, 3))  # 輸出8

這段代碼定義了一個匿名函數(shù)熏瞄,使用了lambda表達式來計算兩個數(shù)的和脚祟。lambda表達式的語法是 lambda 參數(shù)列表: 表達式,在這里强饮,參數(shù)列表為 a, b由桌,表達式為 a + b。然后通過調(diào)用 sum(5, 3) 來使用這個匿名函數(shù)邮丰,傳遞參數(shù)5和3行您,計算它們的和并輸出結(jié)果8。

執(zhí)行此代碼后剪廉,您將在屏幕上看到以下輸出:

8

6. return 語句

專業(yè)理論

return語句用于從函數(shù)返回一個值娃循。

類比理解

把它想象成是你從超市買東西回來,帶回家的東西就是return的值斗蒋。

示例代碼

def add(a, b):
    return a + b

result = add(10, 20)
print(result)  # 輸出30

這段代碼定義了一個名為add的函數(shù)捌斧,接受兩個參數(shù) ab笛质,將它們相加并返回結(jié)果。通過調(diào)用 add(10, 20) 函數(shù)捞蚂,將參數(shù) 10 和 20 傳遞給函數(shù)妇押,計算它們的和并將結(jié)果賦給變量 result。然后使用 print 語句輸出結(jié)果30姓迅。

執(zhí)行此代碼后敲霍,您將在屏幕上看到以下輸出:

30

7. 強制位置參數(shù)

在 Python 3.8 及更高版本中,你可以通過在函數(shù)定義中使用/來指明哪些參數(shù)必須使用位置參數(shù)丁存。

示例代碼

def greet(name, /, greeting="你好"):
    print(f"{greeting}色冀,{name}!")

greet("Alice")
greet("Bob", greeting="您好")

這段代碼定義了一個名為 greet 的函數(shù)柱嫌,接受一個位置參數(shù) name 和一個關(guān)鍵字參數(shù) greeting,其中 name 是位置參數(shù)屯换,不能通過關(guān)鍵字參數(shù)傳遞编丘,而 greeting 是關(guān)鍵字參數(shù),默認(rèn)值為 "你好"彤悔。函數(shù)使用 print 語句輸出拼接好的問候語嘉抓,格式為 "{greeting},{name}晕窑!"抑片。

通過調(diào)用 greet("Alice") 函數(shù),將 "Alice" 作為位置參數(shù)傳遞給函數(shù)杨赤,使用默認(rèn)的問候語輸出敞斋。執(zhí)行此代碼后,您將在屏幕上看到以下輸出:

你好疾牲,Alice植捎!

通過調(diào)用 greet("Bob", greeting="您好") 函數(shù),將 "Bob" 作為位置參數(shù)傳遞給函數(shù)阳柔,并通過關(guān)鍵字參數(shù)傳遞 "您好" 作為自定義的問候語焰枢。執(zhí)行此代碼后,您將在屏幕上看到以下輸出:

您好舌剂,Bob济锄!

通過這些代碼界的樂高積木,您現(xiàn)在可以建造自己的代碼城堡了霍转!記得荐绝,編程就像是玩樂高,越玩越有趣谴忧,而且您可以創(chuàng)造出任何您想象得到的東西很泊。加油角虫,小小編程師,未來等著您去發(fā)現(xiàn)和創(chuàng)造委造!??

模塊:站在巨人的肩膀上:

"用好模塊戳鹅,就像是在巨人的肩膀上俯瞰世界——你可以更遠(yuǎn)、更快地達到目的昏兆。"

嗨枫虏,朋友們!今天我們要開啟一場特別的冒險爬虱,一起學(xué)習(xí)Python的魔法——也就是模塊隶债!想象一下,你是一個魔法師跑筝,而模塊就像是你的魔法書死讹。用好了,可以讓你做很多看似不可能的事情曲梗。那我們就開啟這段旅程吧赞警,準(zhǔn)備好在巨人的肩膀上一覽眾山小虏两!

1. 打開魔法大門:import語句

首先愧旦,讓我們學(xué)習(xí)如何打開魔法大門。使用import語句定罢,就像是告訴Python:“嘿笤虫,我要用這本魔法書的力量啦!”比如說:

import math

這樣一來祖凫,你就可以使用math這本魔法書里的所有咒語了琼蚯,比如math.sqrt(16)能夠幫你計算16的平方根。

我們首先需要導(dǎo)入 math 模塊惠况。下面是應(yīng)用該函數(shù)的示例:

import math

result = math.sqrt(16)
print(result)  # 輸出4.0

在上面的代碼中凌停,我們首先導(dǎo)入了 math 模塊脓魏,然后通過 math.sqrt(16) 計算了 16 的平方根戴尸,并將結(jié)果存儲在變量 result 中。最后驱敲,我們打印 result 的值完箩,將在屏幕上看到諸如"4.0"這樣的輸出赐俗,這就是 16 的平方根。

2. 精確選擇你的魔法:from … import語句

有時候弊知,你可能不需要一整本魔法書阻逮,只需要其中的一兩個咒語。這時候秩彤,from ... import ...就派上用場了:

from math import sqrt

這就好比你從數(shù)學(xué)魔法書中只借了計算平方根的咒語叔扼,現(xiàn)在你可以直接用sqrt()事哭,不用再加math.前綴啦。下面是實現(xiàn)的代碼:

from math import sqrt

result = sqrt(16)
print(result)  # 輸出4.0

在以上代碼中瓜富,我們首先從 math 模塊中導(dǎo)入了 sqrt 函數(shù)鳍咱。然后我們直接使用 sqrt() 函數(shù)計算 16 的平方根,然后把結(jié)果存儲在變量 result 中与柑。最后谤辜,我們打印 result 的值,將在屏幕上看到輸出結(jié)果 "4.0"价捧,這是 16 的平方根丑念。

3. 全部咒語一網(wǎng)打盡:from … import *語句

如果你決定全面學(xué)習(xí)一本魔法書里的所有咒語,可以使用from … import *

from math import *

這句話的意思是:“我想學(xué)會這本書里的所有魔法结蟋!”但記得脯倚,這樣可能會讓你的魔法袋太滿,難以找到想用的咒語哦嵌屎。

當(dāng)使用 from math import * 時挠将,將導(dǎo)入 math 模塊中的所有內(nèi)容,然后可以直接使用 sqrt() 而無需再添加 math. 前綴编整。以下是相關(guān)代碼:

from math import *

result = sqrt(16)
print(result)  # 輸出4.0

在這段代碼中,我們首先導(dǎo)入了 math 模塊的所有內(nèi)容乳丰,然后我們直接調(diào)用 sqrt() 函數(shù)計算 16 的平方根掌测,并將結(jié)果存儲在 result 變量中。最后我們打印 result 的值产园,將在屏幕上看到 "4.0"汞斧,這正是 16 的平方根。

但請注意什燕,使用 from math import * 可能會導(dǎo)致命名空間沖突粘勒。如果其他模塊中有與 math 中的函數(shù)或變量同名的情況,那么最后導(dǎo)入的那個將覆蓋之前導(dǎo)入的同名函數(shù)或變量屎即。為了避免這種情況庙睡,我們通常推薦明確指定所需導(dǎo)入的函數(shù)或變量。

4. 探索魔法的深淵:深入模塊

隨著你對魔法的探索越來越深入技俐,你會發(fā)現(xiàn)乘陪,每個模塊都是一個包含了很多咒語和魔法物品(也就是函數(shù)和變量)的寶箱。你甚至可以創(chuàng)建自己的模塊雕擂,就像寫一本屬于自己的魔法書一樣啡邑。

當(dāng)然,讓我們更詳細(xì)地探討 Python 模塊和包井赌。

在 Python 中谤逼,模塊是一個包含一組相關(guān)代碼的文件贵扰。這些文件可以包含函數(shù)、類流部、變量和其他可執(zhí)行代碼戚绕。Python模塊使得我們可以將代碼劃分為邏輯上的組織單元,并可以在其他地方重復(fù)使用贵涵。

創(chuàng)建和使用模塊

要創(chuàng)建一個模塊列肢,你可以在一個Python文件中編寫你的代碼,并以.py作為文件擴展名宾茂。下面是一個簡單的例子瓷马,展示了如何創(chuàng)建一個模塊:

# mymodule.py
def hello():
    print("Hello from mymodule!")

def add(a, b):
    return a + b

favorite_color = "blue"

在另一個Python文件中,你可以使用import語句來導(dǎo)入模塊跨晴,并使用其中的函數(shù)和變量:

import mymodule

mymodule.hello()  # 輸出 "Hello from mymodule!"
result = mymodule.add(2, 3)  # result 的值為 5
print(mymodule.favorite_color)  # 輸出 "blue"

當(dāng)你導(dǎo)入一個模塊時欧聘,Python解釋器會在搜索路徑中查找該模塊,搜索路徑是一個由多個目錄組成的列表端盆。你可以使用sys模塊的path屬性來查看搜索路徑:

import sys

print(sys.path)

模塊的搜索路徑

Python解釋器將按特定順序搜索模塊的搜索路徑怀骤,一旦找到了匹配的模塊,就會停止搜索焕妙。

搜索路徑通常包括以下位置:

  • 程序的當(dāng)前目錄
  • 與Python解釋器安裝在同一位置的標(biāo)準(zhǔn)庫模塊
  • 用戶自定義的模塊

你還可以將自定義的模塊放在特定的目錄中蒋伦,并將該目錄添加到搜索路徑中,這樣你就可以輕松地導(dǎo)入這些模塊焚鹊。

import sys

sys.path.append("/path/to/my/modules")

這樣痕届,你就可以使用import語句導(dǎo)入位于/path/to/my/modules目錄下的模塊了。

5. 魔法書的集合:包

當(dāng)項目變得更加復(fù)雜末患,包的概念就變得非常有用了研叫。包是一種將相關(guān)模塊組織在一起的方式,可以更好地管理和組織代碼璧针。

創(chuàng)建和使用包

包是一個包含一個或多個模塊的目錄嚷炉,并且包含一個__init__.py文件。這個文件可以是一個空文件探橱,或者包含一些初始化代碼申屹。

下面是一個示例包的目錄結(jié)構(gòu):

mypackage/
    __init__.py
    module_a.py
    module_b.py

module_a.py中,可以定義一些函數(shù)和變量:

# module_a.py
def greet():
    print("Hello from module_a!")

favorite_food = "pizza"

在另一個Python文件中隧膏,你可以使用import語句導(dǎo)入包和其中的模塊:

import mypackage.module_a

mypackage.module_a.greet()  # 輸出 "Hello from module_a!"
print(mypackage.module_a.favorite_food)  # 輸出 "pizza"

另一種導(dǎo)入包和模塊的方法是使用from關(guān)鍵字:

from mypackage import module_b

module_b.goodbye()  # 輸出 "Goodbye from module_b!"

注意独柑,在導(dǎo)入包或模塊時,Python會自動執(zhí)行這些文件中的代碼私植。這樣忌栅,你可以在__init__.py中執(zhí)行一些初始化操作,或者在模塊中定義一些初始化函數(shù)。

通過使用模塊和包索绪,你可以將代碼組織成可重用和易于維護的單元湖员。它們提供了一種將代碼劃分為邏輯組塊的方法,并且在項目的不同部分之間進行共享瑞驱。

6. 魔法書的身份證:__name__屬性

每本魔法書都有自己的名字娘摔。在Python中,__name__屬性是一個特殊的內(nèi)置屬性唤反,用于表示一個模塊的身份標(biāo)識凳寺。

如果一個模塊是作為主程序運行的,它的__name__屬性值是'__main__'彤侍。這個特性可以幫我們區(qū)分模塊是被導(dǎo)入使用肠缨,還是直接運行的。

當(dāng) __name__屬性的值被設(shè)置為__main__盏阶,表示這個模塊是主程序入口文件晒奕。這意味著,通過檢查__name__屬性的值名斟,我們可以判斷一個模塊是被導(dǎo)入還是直接運行脑慧。

舉個例子,假設(shè)我們有兩個模塊:一個名為module1.py砰盐,另一個名為module2.py闷袒。在module1.py中,我們可以添加以下代碼:

def main():
    # 需要執(zhí)行的代碼
    print("這里展示的是本書的魔法岩梳!")

if __name__ == "__main__":
    main()

在這個例子中囊骤,當(dāng)module1.py被直接運行時,__name__屬性的值為__main__蒋腮,就會調(diào)用main()函數(shù)執(zhí)行一些特定的代碼。而當(dāng)module1.py作為模塊被其他模塊導(dǎo)入時藕各,__name__屬性的值就不是__main__池摧,而是模塊的名稱。

通過使用__name__屬性激况,我們可以在一個模塊中區(qū)分出主程序入口和被導(dǎo)入的模塊作彤,并對其進行不同的處理。這在編寫可重用的模塊或腳本時非常有用乌逐。

7. 掌握魔法目錄:dir()函數(shù)

想知道你的魔法書里都有哪些咒語嗎竭讳?使用dir()函數(shù)就可以了,它會告訴你模塊中都有哪些魔法可以使用浙踢。

dir()函數(shù)是一個內(nèi)置函數(shù)绢慢,可以用于獲取給定對象的屬性和方法列表。它返回一個包含對象屬性和方法名稱的排序后的列表洛波。這個函數(shù)對于探索和了解對象的可用功能非常有用胰舆。

下面是dir()函數(shù)的用法示例:

示例1:使用 dir() 獲取模塊的屬性和方法

# 示例1:使用 dir() 獲取模塊的屬性和方法
import math

# 獲取 math 模塊的屬性和方法列表
print(dir(math))

在示例1中骚露,我們導(dǎo)入了math模塊并使用dir(math)來獲取該模塊的屬性和方法列表。

示例2:使用 dir() 獲取內(nèi)置對象的屬性和方法


# 示例2:使用 dir() 獲取內(nèi)置對象的屬性和方法
my_list = [1, 2, 3]

# 獲取列表對象的屬性和方法列表
print(dir(my_list))

在示例2中缚窿,我們創(chuàng)建了一個列表對象my_list棘幸,并使用dir(my_list)來獲取該列表對象的屬性和方法列表。

示例3:使用 dir() 獲取自定義對象的屬性和方法

# 示例3:使用 dir() 獲取自定義對象的屬性和方法
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def say_hello(self):
        print(f"Hello, my name is {self.name}.")

    def get_age(self):
        return self.age

person = Person("Alice", 30)

# 獲取自定義對象的屬性和方法列表
print(dir(person))

上述示例中倦零,我們通過dir()函數(shù)來獲取不同對象的屬性和方法列表误续。在示例3中,我們定義了一個自定義的Person類扫茅,并創(chuàng)建了一個person對象蹋嵌。然后使用dir(person)來獲取該自定義對象的屬性和方法列表。

注意诞帐,dir()函數(shù)返回的列表中包含了對象的所有屬性和方法欣尼,包括內(nèi)置的屬性和方法。但是停蕉,并不是所有的屬性和方法都在表面上可見或可訪問愕鼓。有些屬性和方法可能以雙下劃線開頭,表示它們是對象的私有屬性或方法慧起。

8. 經(jīng)典魔法書:標(biāo)準(zhǔn)模塊

Python有很多內(nèi)置的魔法書菇晃,也就是標(biāo)準(zhǔn)模塊,它們提供了各種各樣的魔法蚓挤,可以幫你做很多事情磺送。

當(dāng)提到 Python 的標(biāo)準(zhǔn)模塊時,我們通常指的是Python內(nèi)置的灿意、無需額外安裝即可使用的模塊估灿。標(biāo)準(zhǔn)模塊提供了各種各樣的功能和工具,可以滿足我們處理不同任務(wù)和解決各種問題的需求缤剧。下面是一些常見的 Python 標(biāo)準(zhǔn)模塊及其功能的表格羅列:

模塊名 功能
math 提供數(shù)學(xué)運算的函數(shù)馅袁,如三角函數(shù)、對數(shù)函數(shù)等
random 生成隨機數(shù)和進行隨機選擇
datetime 處理日期和時間相關(guān)的函數(shù)和類
os 提供與操作系統(tǒng)交互的函數(shù)荒辕,如文件和目錄操作
sys 提供與Python解釋器和系統(tǒng)交互的函數(shù)
json 提供JSON的編碼和解碼功能
csv 讀寫CSV文件的功能
re 提供正則表達式的功能
urllib 進行網(wǎng)絡(luò)請求和處理URL的功能
sqlite3 與SQLite數(shù)據(jù)庫交互的功能

這些只是標(biāo)準(zhǔn)庫中的一小部分模塊汗销,還有許多其他有用的模塊可供探索和使用。通過利用這些標(biāo)準(zhǔn)模塊抵窒,我們可以更加高效地開發(fā)Python應(yīng)用程序弛针,并解決各種實際問題。

9. 從包中借閱所有魔法:from ... import *

當(dāng)你從一個包中使用from ... import *時李皇,Python會導(dǎo)入這個包__init__.py文件中__all__列表指定的所有模塊削茁。這就像是你告訴圖書館管理員:“我要這個書架上的所有魔法書!”

# 在 magic 包的 __init__.py 文件中
__all__ = ['spell', 'charm']

然后,當(dāng)你使用from magic import *時付材,只有spellcharm這兩本書被借閱了朦拖。其他未在all列表中的模塊將不會被導(dǎo)入。

需要注意的是:使用from ... import *語句在大型項目中不被推薦使用厌衔,因為它會導(dǎo)入大量的變量和函數(shù)璧帝,使其難以維護和閱讀。更好的做法是使用顯式的import語句富寿,并只導(dǎo)入需要使用的模塊睬隶、變量或函數(shù)。

朋友們页徐,通過今天的學(xué)習(xí)苏潜,我們學(xué)會了如何借助Python中的模塊和包來做魔法。記住变勇,編程就像是施魔法一樣恤左,只要你有想象力,就沒有什么是不可能的搀绣。希望你們喜歡這次的魔法之旅飞袋,未來的魔法師們,繼續(xù)探索吧链患!

標(biāo)準(zhǔn)庫:Python的瑞士軍刀

標(biāo)準(zhǔn)庫是你的瑞士軍刀巧鸭,無論你面對什么問題,它總有一個工具能來幫忙麻捻。不信纲仍?試試看吧!

歡迎來到Python大冒險的另一章節(jié)贸毕,今天我們要探索的是Python的瑞士軍刀——也就是它的標(biāo)準(zhǔn)庫郑叠!想象你在野外探險,有了瑞士軍刀明棍,無論是切水果還是修理帳篷乡革,都能手到擒來。Python的標(biāo)準(zhǔn)庫也是這樣击蹲,提供了各種各樣的工具署拟,幫你解決編程旅途中遇到的難題婉宰。準(zhǔn)備好了嗎歌豺?讓我們一起來看看這把“瑞士軍刀”都有些什么吧!

1. 操作系統(tǒng)接口(os模塊)

理論講解

os模塊讓你可以和操作系統(tǒng)對話心包,就像是讓你能夠告訴電腦:“嘿类咧,幫我整理下房間!”或者“把這封信郵寄出去『弁铮”

類比理解

想象os模塊是你的個人電腦助手区宇,它可以幫你打開文件夾,創(chuàng)建文件值戳,甚至是運行程序议谷。

代碼示例

當(dāng)你使用Python的os模塊時,你可以通過調(diào)用各種函數(shù)來執(zhí)行諸如文件操作堕虹、目錄操作卧晓、進程管理等系統(tǒng)級任務(wù)。下面是一些os模塊常用函數(shù)的詳細(xì)示例和代碼:

  1. 獲取當(dāng)前工作目錄:
import os

# 獲取當(dāng)前工作目錄
current_dir = os.getcwd()
print("當(dāng)前工作目錄:", current_dir)
  1. 創(chuàng)建目錄:
import os

# 創(chuàng)建單層目錄
os.mkdir("new_directory")

# 創(chuàng)建多層目錄
os.makedirs("new_directory/sub_directory")
  1. 切換目錄:
import os

# 切換到指定目錄
os.chdir("path/to/directory")
  1. 列出目錄內(nèi)容:
import os

# 列出目錄下的所有文件和子目錄
contents = os.listdir("path/to/directory")
print("目錄內(nèi)容:", contents)
  1. 刪除文件或目錄:

注意:慎重選擇刪除的目錄和文件赴捞。

import os

# 刪除文件
os.remove("path/to/file.txt")

# 刪除空目錄
os.rmdir("empty_directory")

# 刪除非空目錄及其內(nèi)容
os.removedirs("directory_to_remove")
  1. 重命名文件或目錄:
import os

# 重命名文件
os.rename("old_file.txt", "new_file.txt")

# 重命名目錄
os.rename("old_directory", "new_directory")
  1. 運行系統(tǒng)命令:
import os

# 調(diào)用系統(tǒng)命令
os.system("command")
  1. 檢查文件或目錄是否存在:
import os

# 檢查文件是否存在
if os.path.exists("path/to/file.txt"):
    print("文件存在")

# 檢查目錄是否存在
if os.path.exists("path/to/directory"):
    print("目錄存在")

以上只是一些os模塊常用函數(shù)的示例逼裆,還有更多功能和方法可供探索。你可以查閱Python官方文檔以獲取更詳細(xì)的信息和更多示例代碼赦政。

2. 文件通配符(glob模塊)

理論講解

使用glob模塊胜宇,你可以找到符合特定規(guī)則的文件名,就像是玩寶藏游戲恢着,通過線索找到寶藏桐愉。

類比理解

假設(shè)你有一個箱子,里面裝滿了各種玩具然评,使用glob就像是你說:“我只想找到所有的小汽車玩具仅财。”

代碼示例

Python中的glob模塊可用于使用通配符查找文件和目錄的名稱碗淌。這是一種非常方便的方式盏求,例如,當(dāng)你需要查找所有擴展名為.txt.py的文件時亿眠,可以使用glob模塊碎罚。下面是一些glob模塊常用函數(shù)的詳細(xì)示例和代碼:

  1. 查找所有擴展名為.txt的文件:
import glob

# 找到當(dāng)前目錄下所有的.txt文件
txt_files = glob.glob('*.txt')

# 判斷是否找到了任何.txt文件
if txt_files:
    # 輸出所有的.txt文件
    for file in txt_files:
        print(file)
else:
    # 如果沒有找到任何.txt文件,則輸出一個消息
    print("在當(dāng)前目錄下沒有找到任何.txt文件纳像。請檢查您的目錄或者更改到包含.txt文件的目錄試一試荆烈。")
  1. 遞歸查找所有擴展名為.py的文件:
import glob

# 在當(dāng)前目錄及其所有子目錄中查找所有的.py文件
py_files = glob.glob('**/*.py', recursive=True)

# 輸出所有的.py文件
for file in py_files:
    print(file)
  1. 使用多個通配符:
import glob

# 在當(dāng)前目錄中查找所有以'a'開頭,擴展名為.txt或.py的文件
matched_files = glob.glob('a*.[tp][xy]')

# 輸出匹配的文件
for file in matched_files:
    print(file)

請注意竟趾,glob.glob()函數(shù)返回的是一個列表憔购,其中包含所有匹配的文件和目錄。如果沒有找到任何匹配的文件或目錄岔帽,那么返回的列表將為空玫鸟。

3. 命令行參數(shù)(sys模塊)

理論講解

通過sys模塊的argv屬性,你可以讀取命令行上輸入的參數(shù)犀勒,讓你的程序更加靈活屎飘,能根據(jù)不同的輸入做出不同的響應(yīng)妥曲。

在 Python 中,我們可以使用sys模塊的sys.argv來處理命令行參數(shù)钦购。sys.argv是一個包含命令行參數(shù)的列表檐盟,其中sys.argv[0]通常是腳本的名稱,而其他元素則是傳遞給腳本的參數(shù)押桃。

類比理解

就像是你玩電子游戲時葵萎,可以通過控制器輸入指令讓角色做出相應(yīng)的動作。

代碼示例

下面是一些如何使用sys.argv處理命令行參數(shù)的示例:

  1. 輸出所有的命令行參數(shù):
    這個腳本將打印所有傳遞給它的命令行參數(shù)唱凯。
import sys

# 輸出命令行參數(shù)
for arg in sys.argv:
    print(arg)
  1. 使用命令行參數(shù)進行計算:
    這個腳本接收兩個命令行參數(shù)陌宿,并把它們作為整數(shù)相加。
import sys

# 確保有兩個參數(shù)被傳入
if len(sys.argv) == 3:
    # 將參數(shù)轉(zhuǎn)化為整數(shù)并相加
    result = int(sys.argv[1]) + int(sys.argv[2])
    print(result)
else:
    print("請?zhí)峁﹥蓚€整數(shù)參數(shù)波丰。")

您可以通過運行 python script.py arg1 arg2 來運行以上腳本壳坪。請注意,命令行參數(shù)始終作為字符串提供掰烟,所以在進行數(shù)學(xué)運算之前需要將它們轉(zhuǎn)換為合適的數(shù)值類型爽蝴。

4. 錯誤輸出重定向和程序終止(sys模塊)

理論講解

有時候,程序出錯了纫骑,你可能不希望用戶看到那些令人困惑的錯誤信息蝎亚,sys模塊讓你可以把錯誤信息輸出到別的地方,或者干脆優(yōu)雅地退出程序先馆。

在Python中发框,sys模塊提供了一種方法來重定向錯誤輸出和終止程序。這主要與sys.stderrsys.exit()相關(guān)煤墙。

類比理解

想象你在做魔術(shù)梅惯,出了點小差錯,你可以用一塊布遮住仿野,然后悄悄地退出舞臺铣减。

代碼示例

  1. 錯誤輸出重定向: sys.stderr是用來處理錯誤消息和診斷輸出的標(biāo)準(zhǔn)錯誤流。您可以利用這個特性來重定向錯誤輸出脚作。例如葫哗,我們可以把錯誤消息重定向到一個文件中去:
import sys

sys.stderr = open('errorlog.txt', 'w')  #重定向錯誤輸出到一個文件

try:
    x = 1 / 0  #這將產(chǎn)生一個ZeroDivisionError
except Exception as e:
    sys.stderr.write(str(e))  #將錯誤信息寫入到剛才的文件

在上面的例子中,零除錯誤的信息將會寫入到errorlog.txt文件中球涛,而不是輸出到屏幕上劣针。

  1. 程序終止: sys.exit()函數(shù)用于退出Python程序。當(dāng)你調(diào)用這個函數(shù)時亿扁,Python解釋器會退出捺典。您可以傳遞一個參數(shù)給sys.exit()來指示程序的退出狀態(tài)。返回0表示成功終止魏烫,非零表示有錯誤發(fā)生辣苏。例如:
import sys

try:
    x = 1 / 0  #這將產(chǎn)生一個ZeroDivisionError
except Exception:
    sys.exit(1)  #發(fā)生錯誤時,使用非零退出狀態(tài)

在這個例子中哄褒,當(dāng)我們遇到一個錯誤時稀蟋,Python程序?qū)⒘⒓唇K止,并返回一個非零退出狀態(tài)呐赡。

5. 字符串模式匹配(re模塊)

理論講解

在 Python中退客,可以使用re模塊來進行字符串模式匹配。re模塊提供了一組函數(shù)和正則表達式(也稱為模式)來進行字符串匹配和搜索操作链嘀。

re模塊讓你可以在文本中搜索符合特定模式(規(guī)則)的字符串萌狂,就像是在海灘上用篩子篩沙子,找到珍珠怀泊。

類比理解

假設(shè)你在一本書中尋找所有提到“

寶藏”的地方茫藏,re模塊就是你的放大鏡。

代碼示例

下面是一些使用re模塊進行字符串模式匹配的示例:

  1. 匹配字符串: 使用re.match()函數(shù)可以嘗試從字符串的開頭開始匹配一個模式霹琼。如果成功匹配务傲,它將返回一個匹配對象;否則返回None枣申。
import re

pattern = r"Hello"
text = "Hello, World!"

match = re.match(pattern, text)

if match:
    print("匹配成功售葡!")
else:
    print("匹配失敗忠藤!")

在上面的例子中挟伙,我們嘗試從字符串的開頭匹配模式Hello。由于字符串中的開頭恰好是Hello模孩,所以匹配成功尖阔,輸出匹配成功!榨咐。

  1. 搜索字符串: 使用re.search()函數(shù)可以在整個字符串中搜索模式并返回第一個匹配項诺祸。如果匹配成功环葵,它將返回一個匹配對象像棘;否則返回None充蓝。
import re

pattern = r"World"
text = "Hello, World!"

search = re.search(pattern, text)

if search:
    print("找到匹配厘熟!")
else:
    print("未找到匹配伞剑!")

在上面的例子中撰豺,我們在字符串中搜索模式World蹬铺。由于字符串中存在World越平,所以搜索成功昌跌,輸出找到匹配仰禀!

  1. 提取匹配內(nèi)容: 使用匹配對象的方法和屬性蚕愤,可以提取匹配的內(nèi)容答恶。例如饺蚊,使用group()方法可以獲取整個匹配的內(nèi)容。
import re

pattern = r"(\w+), (\w+)!"
text = "Hello, World!"

match = re.search(pattern, text)

if match:
    print("完整匹配: ", match.group())
    print("第一個捕獲組: ", match.group(1))
    print("第二個捕獲組: ", match.group(2))

在上面的例子中悬嗓,我們定義了一個模式(\w+), (\w+)!污呼,其中使用了兩個捕獲組來匹配逗號前后的單詞。通過匹配對象的group()方法包竹,我們可以提取出完整匹配的內(nèi)容以及每個捕獲組的內(nèi)容燕酷。

  1. 提取有用信息: 在一段文本中找到所有的電子郵件地址
import re

# 在一段文本中找到所有的電子郵件地址
text = "Contact us at support@example.com or sales@example.com."
emails = re.findall(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', text)
print(emails)

6. 數(shù)學(xué)(math模塊)

理論講解

math模塊提供了一系列的數(shù)學(xué)運算工具,無論是簡單的加減乘除周瞎,還是復(fù)雜的三角函數(shù)計算苗缩,都能輕松搞定。

在Python中声诸,math模塊提供了許多常用的數(shù)學(xué)函數(shù)和常量酱讶,用于進行數(shù)學(xué)運算和數(shù)值計算。您可以使用import math語句導(dǎo)入math模塊彼乌,然后使用其中的函數(shù)和常量浴麻。

類比理解

想象你在建造一座城堡,math模塊就是你的工具箱囤攀,里面有各種工具幫你精確計算软免。

代碼示例

下面是一些常用的math模塊函數(shù)和常量的示例:

  1. 數(shù)學(xué)函數(shù):
  • math.sqrt(x): 返回數(shù) x 的平方根。
  • math.pow(x, y): 返回 xy 次冪焚挠。
  • math.exp(x): 返回 ex 次冪膏萧,其中 e 是自然對數(shù)的底數(shù)。
  • math.log(x): 返回 x 的自然對數(shù)(以 e 為底)蝌衔。
  • math.sin(x): 返回角度 x 的正弦值榛泛,其中 x 以弧度為單位。
  • math.cos(x): 返回角度 x 的余弦值噩斟,其中 x 以弧度為單位曹锨。
  • math.tan(x): 返回角度 x 的正切值,其中 x 以弧度為單位剃允。
import math

x = 16
y = 2
angle = math.pi / 4

# 平方根
print("平方根:", math.sqrt(x))

# x 的 y 次冪
print("次冪:", math.pow(x, y))

# e 的 x 次冪
print("指數(shù):", math.exp(x))

# x 的自然對數(shù)
print("自然對數(shù):", math.log(x))

# 正弦值
print("正弦值:", math.sin(angle))

# 余弦值
print("余弦值:", math.cos(angle))

# 正切值
print("正切值:", math.tan(angle))
  1. 常用常量:
  • math.pi: 圓周率 π 的近似值沛简。
  • math.e: 自然對數(shù)的底數(shù) e 的近似值。
import math

# 圓周率
print("π 的值:", math.pi)

# 自然對數(shù)的底數(shù)
print("e 的值:", math.e)

希望這些示例能幫助您了解如何使用math模塊進行數(shù)學(xué)運算和數(shù)值計算斥废。

7. 互聯(lián)網(wǎng)訪問(urllib模塊)

理論講解

在Python中椒楣,urllib模塊是一個用于處理URL(統(tǒng)一資源定位器)的庫。它提供了一組功能強大的工具牡肉,用于進行HTTP請求捧灰、處理URL編碼和解碼以及其他與網(wǎng)絡(luò)訪問相關(guān)的操作。

使用urllib模塊统锤,你可以讓你的程序訪問互聯(lián)網(wǎng)毛俏,就像是給它一個通往外面世界的門炭庙。

類比理解

想象你的程序是一只寵物,urllib就是它的遛狗繩煌寇,讓它可以安全地在互聯(lián)網(wǎng)上散步焕蹄。

代碼示例

下面是一些常用的urllib模塊函數(shù)的示例:

  1. HTTP請求:
  • urllib.request.urlopen(url): 打開指定的URL,并返回一個類似于文件對象的response對象唧席,可以從中讀取服務(wù)器響應(yīng)的內(nèi)容。
import urllib.request

url = "https://www.example.com"

response = urllib.request.urlopen(url)
data = response.read().decode("utf-8")
print(data)
  1. URL編碼和解碼:
  • urllib.parse.quote(string): 對字符串進行URL編碼嘲驾。
  • urllib.parse.unquote(string): 對URL編碼的字符串進行解碼淌哟。
import urllib.parse

url = "https://www.example.com/?q=Python urllib"

# URL編碼
encoded_url = urllib.parse.quote(url)
print("編碼后的URL:", encoded_url)

# URL解碼
decoded_url = urllib.parse.unquote(encoded_url)
print("解碼后的URL:", decoded_url)
  1. 其他操作:
  • urllib.request.urlretrieve(url, filename): 從指定URL下載文件,并保存到本地指定的文件路徑辽故。
import urllib.request

url = "https://www.python.org/static/img/python-logo@2x.png"
filename = "image.jpg"

urllib.request.urlretrieve(url, filename)
print("文件下載完成")

這些示例演示了如何使用urllib模塊進行基本的互聯(lián)網(wǎng)訪問操作徒仓,包括發(fā)送HTTP請求、處理URL編碼和解碼以及文件下載誊垢。如果您有任何其他問題掉弛,請隨時提問!

8. 日期和時間(datetime模塊)

理論講解

datetime模塊讓你可以在程序中處理日期和時間喂走,就像是給你的程序加上了一個內(nèi)置的日歷和鬧鐘殃饿。

在 Python 中,datetime模塊提供了處理日期和時間的功能芋肠。它包含了幾個類和函數(shù)乎芳,用于創(chuàng)建、操作和格式化日期和時間對象帖池。

類比理解

想象你正在規(guī)劃一個派對奈惑,datetime模塊就是你的助手,幫你記住派對的日期和開始時間睡汹。

代碼示例

下面是一些常用的datetime模塊的類和函數(shù):

  1. 日期和時間對象:
  • datetime.datetime: 表示一個特定的日期和時間肴甸。
  • datetime.date: 表示一個特定的日期。
  • datetime.time: 表示一個特定的時間囚巴。
  1. 獲取當(dāng)前日期和時間:
  • datetime.datetime.now(): 返回當(dāng)前的日期和時間原在。
  • datetime.date.today(): 返回當(dāng)前的日期。
import datetime

# 獲取當(dāng)前日期和時間
current_datetime = datetime.datetime.now()
print("當(dāng)前日期和時間:", current_datetime)

# 獲取當(dāng)前日期
current_date = datetime.date.today()
print("當(dāng)前日期:", current_date)
  1. 日期和時間的格式化:

strftime(format): 將日期和時間對象格式化為指定的字符串形式彤叉。

  • %Y: 四位數(shù)的年份(例如:2022)
  • %m: 月份(01~12)
  • %d: 一個月中的第幾天(01~31)
  • %H: 小時(00~23)
  • %M: 分鐘(00~59)
  • %S: 秒(00~59)
import datetime

# 格式化當(dāng)前日期和時間
current_datetime = datetime.datetime.now()
formatted_datetime = current_datetime.strftime("%Y-%m-%d %H:%M:%S")
print("格式化后的日期和時間:", formatted_datetime)

# 格式化當(dāng)前日期
current_date = datetime.date.today()
formatted_date = current_date.strftime("%Y-%m-%d")
print("格式化后的日期:", formatted_date)
  1. 日期和時間的計算:

datetime.timedelta類可以在日期和時間上執(zhí)行簡單的數(shù)學(xué)運算晤斩。

import datetime

# 當(dāng)前日期和時間
current_datetime = datetime.datetime.now()
print("當(dāng)前日期和時間:", current_datetime)

# 增加一天
next_day = current_datetime + datetime.timedelta(days=1)
print("明天的日期和時間:", next_day)

# 減少一小時
previous_hour = current_datetime - datetime.timedelta(hours=1)
print("一小時前的日期和時間:", previous_hour)

這些示例演示了如何使用datetime模塊處理日期和時間,包括創(chuàng)建日期和時間對象姆坚、獲取當(dāng)前日期和時間澳泵、格式化日期和時間以及進行日期和時間的計算。

9. 數(shù)據(jù)壓縮(zlib模塊)

理論講解

在Python中兼呵,zlib模塊提供了用于數(shù)據(jù)壓縮和解壓縮的功能兔辅。它基于 DEFLATE 算法腊敲,可以有效地壓縮和解壓縮數(shù)據(jù)。

zlib模塊讓你可以在程序中壓縮和解壓數(shù)據(jù)维苔,就像是用一個魔法袋子碰辅,可以把大象裝進冰箱。

類比理解

想象你的電腦硬盤快滿了介时,zlib就是幫你節(jié)省空間的工具没宾。

代碼示例

下面是一些常用的zlib模塊的函數(shù):

  1. 壓縮數(shù)據(jù):
  • zlib.compress(data, level=-1): 壓縮給定的數(shù)據(jù)。
    • data: 要壓縮的數(shù)據(jù)沸柔,可以是字符串或字節(jié)串循衰。
    • level (可選): 壓縮級別,取值范圍為 0-9褐澎,其中 0 表示無壓縮会钝,9 表示最大壓縮。默認(rèn)值為 -1工三,表示默認(rèn)壓縮級別迁酸。
import zlib

# 原始數(shù)據(jù)
data = b"This is some data that needs to be compressed."

# 壓縮數(shù)據(jù)
compressed_data = zlib.compress(data)
print("壓縮后的數(shù)據(jù):", compressed_data)
  1. 解壓縮數(shù)據(jù):
  • zlib.decompress(data): 解壓縮給定的數(shù)據(jù)。
    • data: 要解壓縮的數(shù)據(jù)俭正,可以是字符串或字節(jié)串奸鬓。
import zlib

# 原始數(shù)據(jù)
data = b"This is some data that needs to be compressed."

# 壓縮數(shù)據(jù)
compressed_data = zlib.compress(data)

# 壓縮后的數(shù)據(jù)
compressed_data = b'x\x9c\x0b\xc9\xc8,V\x00\xa2\xe2\xfc\xdcT\x85\x94\xc4\x92D\x85\x92\x8c\xc4\x12\x85\xbc\xd4\xd4\x94b\x85\x92|\x85\xa4T\x85\xe4\xfc\xdc\x82\xa2\xd4\xe2\xe2\xd4\x14=\x00\x81\xd2\x10\x90'

# 解壓縮數(shù)據(jù)
decompressed_data = zlib.decompress(compressed_data)
print("解壓縮后的數(shù)據(jù):", decompressed_data)

以上示例演示了如何使用zlib模塊來壓縮和解壓縮數(shù)據(jù)。請注意掸读,壓縮后的數(shù)據(jù)是字節(jié)串(bytes)全蝶,因此在解壓縮時需要使用相同的數(shù)據(jù)類型。

10. 性能測量(timeit模塊)

理論講解

timeit模塊可以幫你測量一段代碼的執(zhí)行時間寺枉,就像是一個專業(yè)的計時器抑淫,幫你找出程序中執(zhí)行慢的點。

在Python中姥闪,可以使用timeit模塊來測量代碼的性能始苇。timeit模塊提供了一個簡單的方式來確定給定代碼塊的執(zhí)行時間。

類比理解

想象你在訓(xùn)練短跑筐喳,timeit就是記錄你每次跑步時間的教練催式。

代碼示例

下面是一些常用的timeit模塊的函數(shù):

  • timeit.timeit(stmt, setup, timer, number): 測量給定代碼塊的執(zhí)行時間。
    • stmt: 要測量執(zhí)行時間的代碼塊避归。
    • setup: 設(shè)置代碼塊所需的設(shè)置和初始化荣月。
    • timer (可選): 指定測量時間的定時器,默認(rèn)為系統(tǒng)提供的定時器梳毙。
    • number (可選): 執(zhí)行代碼塊的次數(shù)哺窄,默認(rèn)為1。

下面是一個示例,演示如何使用timeit模塊測量代碼塊的執(zhí)行時間:

import timeit

# 定義代碼塊
code = '''
for i in range(1000):
    print(i)
'''

# 測量執(zhí)行時間
execution_time = timeit.timeit(stmt=code, number=1)
print("執(zhí)行時間:", execution_time, "秒")
import timeit

# 測量代碼執(zhí)行時間
execution_time = timeit.timeit('"-".join(str(n) for n in range(100))', number=10000)
print(f"Execution time: {execution_time}")

請注意萌业,timeit模塊默認(rèn)情況下會執(zhí)行代碼塊一次坷襟,并返回執(zhí)行時間。您可以更改number參數(shù)的值來多次執(zhí)行代碼塊生年,并獲得平均執(zhí)行時間婴程。

11. 質(zhì)量控制(doctest和 unittest 模塊)

理論講解

在Python中,有兩個常用的模塊用于實施質(zhì)量控制:doctestunittest抱婉。

使用doctestunittest模塊档叔,你可以為你的程序編寫測試,確保它運行正常蒸绩,就像是給你的程序做健康檢查衙四。

類比理解

想象你的程序是一輛車,doctestunittest就是定期檢查侵贵,確保它不會在路上拋錨届搁。

代碼示例

1. doctest模塊: doctest模塊提供了一種簡單的方式來編寫和執(zhí)行文檔中的示例代碼缘薛,并驗證其正確性窍育。這些示例代碼通常用于測試函數(shù)、類或模塊的行為宴胧。

使用doctest模塊的步驟如下:

  • 在函數(shù)漱抓、類或模塊的文檔字符串中編寫示例代碼,示例代碼通常以>>>作為前綴恕齐。
  • 使用doctest模塊的testmod()函數(shù)執(zhí)行文檔字符串中的示例代碼乞娄,并進行驗證。

下面是一個示例显歧,演示如何使用doctest模塊進行質(zhì)量控制:

import doctest

def add(a, b):
    """
    返回兩個數(shù)字的和仪或。

    示例用法:
    >>> add(2, 3)
    5
    >>> add(-1, 5)
    4
    """

    return a + b

# 執(zhí)行doctest
doctest.testmod()

運行上述代碼將自動執(zhí)行文檔字符串中的示例代碼,并進行驗證士骤。

如果把

>>> add(2, 3)
5

改成

>>> add(2, 3)
6

再執(zhí)行代碼范删,會提示以下信息,提示我們改動的內(nèi)容引起測試用例的不通過拷肌,進而推動我們?nèi)バ迯?fù)有錯誤的代碼或用例到旦。

**********************************************************************
File "/Users/wujie/Python/test-demo/test_os.py", line 8, in __main__.add
Failed example:
    add(2, 3)
Expected:
    6
Got:
    5
**********************************************************************
1 items had failures:
   1 of   2 in __main__.add
***Test Failed*** 1 failures.

2. unittest模塊: unittest模塊是Python中用于編寫單元測試的內(nèi)置模塊。它提供了一個類和一些斷言方法巨缘,可以用于編寫測試用例添忘、運行測試并生成測試報告。

使用unittest模塊的步驟如下:

  • 創(chuàng)建一個繼承自unittest.TestCase的測試類若锁。
  • 在測試類中定義測試方法搁骑,方法名以test_開頭。
  • 在測試方法中使用斷言方法來驗證函數(shù)或類的行為是否符合預(yù)期。

下面是一個示例靶病,演示如何使用unittest模塊進行質(zhì)量控制:

import unittest

def add(a, b):
    return a + b

class TestAddFunction(unittest.TestCase):

    def test_add_positive_numbers(self):
        result = add(2, 3)
        self.assertEqual(result, 5)

    def test_add_negative_numbers(self):
        result = add(-1, -5)
        self.assertEqual(result, -6)

if __name__ == '__main__':
    unittest.main()

運行上述代碼將執(zhí)行測試類中的所有測試方法会通,并生成測試報告。

doctestunittest模塊都是非常有用的工具娄周,可以幫助您確保代碼的質(zhì)量和正確性涕侈。您可以根據(jù)自己的需求選擇適合的模塊進行質(zhì)量控制。

12. 自帶電池

理論講解

Python 的標(biāo)準(zhǔn)庫被稱為“自帶電池”煤辨,這意味著Python自帶了一套功能齊全的標(biāo)準(zhǔn)庫裳涛,幾乎能覆蓋你在開發(fā)中遇到的所有需求。

類比理解

想象你買了一個新玩具众辨,發(fā)現(xiàn)盒子里已經(jīng)附帶了電池端三,這樣你就可以立即開始玩耍,而不需要去商店另買電池鹃彻。

格式化輸出:讓數(shù)據(jù)像穿上西裝打領(lǐng)帶

在Python中郊闯,可以使用格式化字符串來實現(xiàn)數(shù)據(jù)的精確輸出。

比如蛛株,想象一下团赁,你拍了一張超級酷炫的照片,想要把它發(fā)給朋友看谨履,但直接發(fā)過去就那么…隨便欢摄。如果把它裝進一個漂亮的相框里,那不是更有看頭嗎笋粟?

格式化輸出就是Python里的“相框”怀挠,它能讓你的數(shù)據(jù)看起來整整齊齊,美美噠害捕。以下是一些常用的格式化輸出方法:

  1. 百分號(%)格式化字符串示例:
name = '小明'
age = 18
print("我叫 %s绿淋,今年 %d 歲。" % (name, age))

輸出結(jié)果:

我叫 小明尝盼,今年 18 歲吞滞。
  1. .format()方法格式化字符串示例:
name = '小紅'
age = 20
print("我叫 {},今年 {} 歲东涡。".format(name, age))

輸出結(jié)果:

我叫 小紅冯吓,今年 20 歲。
  1. f-string格式化字符串示例:
name = '小李'
age = 22
print(f"我叫 {name}疮跑,今年 {age} 歲组贺。")

輸出結(jié)果:

我叫 小李,今年 22 歲祖娘。

這些示例展示了如何使用不同的格式化方法來輸出中文數(shù)據(jù)失尖。通過選擇合適的格式化方式啊奄,并根據(jù)需要添加自定義的文本,您可以使數(shù)據(jù)以規(guī)范和優(yōu)雅的方式呈現(xiàn)掀潮,就像穿上西裝打領(lǐng)帶一樣菇夸。

模板:變量填空大師

假如你在寫邀請函,每封信的內(nèi)容都差不多仪吧,只是名字和日期要根據(jù)人來變庄新。這時,你就可以用模板薯鼠,先把框架搭好择诈,哪里需要變動,就在哪里挖個坑出皇。用的時候羞芍,只需往坑里填東西就行了。確實郊艘,Python的標(biāo)準(zhǔn)庫被稱為“自帶電池”荷科,因為它包含了各種功能豐富的模塊和工具,可以滿足大多數(shù)常見的編程需求纱注,而無需額外安裝第三方庫畏浆。

以下是使用Python標(biāo)準(zhǔn)庫實現(xiàn)變量填空的示例代碼:

  1. 使用字符串的format方法實現(xiàn)變量填空:
# 定義要填充的變量
name = "小明"
age = 18

# 創(chuàng)建一個包含變量占位符的字符串
template = "我的名字是{},今年{}歲奈附。"

# 使用format方法進行變量填空
result = template.format(name, age)
print(result)

輸出結(jié)果:

我的名字是小明全度,今年18歲煮剧。
  1. 使用%運算符實現(xiàn)變量填空:
# 定義要填充的變量
name = "小紅"
gender = "女性"

# 創(chuàng)建一個包含變量占位符的字符串
template = "%s是一位%s工程師斥滤。"

# 使用%運算符進行變量填空
result = template % (name, gender)
print(result)

輸出結(jié)果:

小紅是一位女性工程師。

這些示例演示了如何在Python中使用標(biāo)準(zhǔn)庫實現(xiàn)變量填空的效果勉盅。

使用二進制數(shù)據(jù)記錄格式:秘密通道的信息傳遞

想象你是個間諜佑颇,需要傳遞一些秘密信息,但又不能讓別人一眼看出來草娜。這時挑胸,你可以用二進制格式來記錄這些信息。對別人來說宰闰,它們就像是看不懂的密碼茬贵,但對你和你的接頭人來說,卻能清晰地交流信息移袍。

對于秘密通道的信息傳遞解藻,您可以使用Python標(biāo)準(zhǔn)庫中的struct模塊來處理二進制數(shù)據(jù)。struct模塊提供了一種將數(shù)據(jù)轉(zhuǎn)換為二進制表示葡盗,或從二進制表示中提取數(shù)據(jù)的方式螟左。

以下是一個使用struct模塊處理二進制數(shù)據(jù)的示例代碼:

import struct

# 定義要傳遞的秘密消息
message = "這是一條秘密消息!"

# 將消息轉(zhuǎn)換為二進制表示
binary_data = message.encode()

# 將二進制數(shù)據(jù)寫入文件
with open("secret_message.bin", "wb") as file:
    file.write(binary_data)

# 從文件中讀取二進制數(shù)據(jù)
with open("secret_message.bin", "rb") as file:
    binary_data = file.read()

# 將二進制數(shù)據(jù)轉(zhuǎn)換回消息
decoded_message = binary_data.decode()
print(decoded_message)

輸出結(jié)果:

這是一條秘密消息!

在這個示例中胶背,我們首先將秘密消息轉(zhuǎn)換為二進制表示巷嚣,并將其寫入一個名為"secret_message.bin"的文件中。然后钳吟,我們從文件中讀取二進制數(shù)據(jù)廷粒,并將其轉(zhuǎn)換回原始的消息格式。

這只是使用Python標(biāo)準(zhǔn)庫處理二進制數(shù)據(jù)的一個簡單示例红且。根據(jù)實際需求评雌,您可以使用struct模塊進行更復(fù)雜的操作,例如解析具有特定結(jié)構(gòu)的二進制數(shù)據(jù)直焙。

多線程:多個超人同時出擊

如果你需要同時做很多事景东,比如說,邊打怪獸奔誓,邊救公主斤吐,邊做飯。這時候厨喂,你就需要多線程技能和措,它能讓你的程序同時處理多個任務(wù),就像有好幾個你在同時行動一樣蜕煌。

在 Python 中派阱,您可以使用threading模塊來實現(xiàn)多線程編程。多線程允許多個線程同時執(zhí)行斜纪,就像多個超人同時出擊一樣贫母。

以下是一個使用threading模塊實現(xiàn)多線程的中文示例代碼:

import threading
import time

# 定義一個函數(shù)作為線程的執(zhí)行體
def sing():
    for i in range(5):
        print("線程1正在唱歌")
        time.sleep(0.1) # 睡0.1s為了增強線程交替執(zhí)行的效果


# 定義另一個函數(shù)作為線程的執(zhí)行體
def dance():
    for i in range(5):
        print("線程2正在跳舞")
        time.sleep(0.1) # 睡0.1s為了增強線程交替執(zhí)行的效果

# 創(chuàng)建線程對象
thread1 = threading.Thread(target=sing)
thread2 = threading.Thread(target=dance)

# 啟動線程
thread1.start()
thread2.start()

# 等待線程執(zhí)行結(jié)束
thread1.join()
thread2.join()

print("主線程結(jié)束")

輸出結(jié)果:

線程1正在唱歌
線程2正在跳舞
線程1正在唱歌
線程2正在跳舞
線程1正在唱歌
線程2正在跳舞
線程1正在唱歌
線程2正在跳舞
線程1正在唱歌
線程2正在跳舞
主線程結(jié)束

在這個示例中,我們定義了兩個函數(shù)singdance作為兩個線程的執(zhí)行體盒刚。然后腺劣,我們創(chuàng)建了兩個線程對象thread1thread2,并通過調(diào)用start方法來啟動線程因块。線程會同時執(zhí)行橘原,輸出唱歌和跳舞的信息。

最后涡上,我們使用join方法等待線程執(zhí)行結(jié)束趾断,然后輸出"主線程結(jié)束"的信息。

這只是使用Python標(biāo)準(zhǔn)庫實現(xiàn)多線程的一個簡單示例吩愧。根據(jù)實際需求芋酌,您可以使用threading模塊進行更復(fù)雜的多線程編程。

日志記錄:冒險日記

每個冒險家都需要一本日記耻警,記錄下自己的冒險歷程隔嫡。Python中的日志記錄就是這樣一個功能甸怕,它能幫你記錄下程序運行的每一個重要時刻,方便你回頭查看腮恩,也方便你找出問題所在梢杭。

在Python中,您可以使用logging模塊來實現(xiàn)日志記錄秸滴。日志記錄允許您記錄程序的運行過程武契、錯誤信息以及其他有用的信息,就像寫冒險日記一樣荡含。

以下是一個使用logging模塊實現(xiàn)日志記錄的中文示例代碼:

import logging

# 配置日志輸出的格式
logging.basicConfig(
    level=logging.DEBUG,
    format="%(asctime)s - %(levelname)s - %(message)s"
)

# 創(chuàng)建日志記錄器
logger = logging.getLogger("my_logger")

# 記錄不同級別的日志
logger.debug("這是一個調(diào)試級別的日志")
logger.info("這是一個信息級別的日志")
logger.warning("這是一個警告級別的日志")
logger.error("這是一個錯誤級別的日志")
logger.critical("這是一個嚴(yán)重級別的日志")

輸出結(jié)果:

2024-03-27 22:54:42,957 - DEBUG - 這是一個調(diào)試級別的日志
2024-03-27 22:54:42,957 - INFO - 這是一個信息級別的日志
2024-03-27 22:54:42,957 - WARNING - 這是一個警告級別的日志
2024-03-27 22:54:42,957 - ERROR - 這是一個錯誤級別的日志
2024-03-27 22:54:42,958 - CRITICAL - 這是一個嚴(yán)重級別的日志

在這個示例中咒唆,我們首先使用basicConfig函數(shù)配置了日志的輸出格式和級別。然后释液,我們創(chuàng)建了一個名為"my_logger"的日志記錄器全释。

接下來,我們使用不同的日志級別調(diào)用logger對象的方法误债,如debug浸船、infowarning寝蹈、errorcritical李命,并傳入相應(yīng)的日志信息。每條日志記錄都包括了時間戳箫老、日志級別和日志信息封字。

這只是使用Python標(biāo)準(zhǔn)庫實現(xiàn)日志記錄的一個簡單示例。根據(jù)實際需求耍鬓,您可以使用logging模塊進行更復(fù)雜的日志記錄阔籽,如記錄到文件、設(shè)置不同的日志處理器和格式等界斜。

弱引用:記憶中的幽靈

想象你的大腦有限仿耽,不能記住所有人的名字合冀,只記住那些經(jīng)常見到的人各薇。對于那些偶爾遇到的,你選擇"弱記憶"他們的名字君躺,一旦那人離開了你的視線峭判,他的名字就從你腦海中消失。弱引用在Python里也是這么個意思棕叫,它不會強行把對象留在內(nèi)存里林螃,用完即走,非常節(jié)省空間俺泣。

在Python中疗认,弱引用是一種特殊類型的引用完残,它不會增加對象的引用計數(shù)。這意味著横漏,當(dāng)只存在弱引用指向某個對象時谨设,該對象可能會被垃圾回收器回收。弱引用通常用于解決循環(huán)引用的問題缎浇,避免內(nèi)存泄漏扎拣。

以下是一個使用weakref模塊處理弱引用的中文示例代碼:

import weakref

# 定義一個類
class Person:
    def __init__(self, name):
        self.name = name

    def say_hello(self):
        print(f"你好,我是{self.name}")

# 創(chuàng)建一個弱引用
person = Person("小明")
ref = weakref.ref(person)

# 通過弱引用訪問對象
ref().say_hello()  # 輸出:你好素跺,我是小明

# 釋放原始對象的引用
person = None

# 弱引用無法訪問原始對象
print(ref())  # 輸出:None

在這個示例中二蓝,我們定義了一個名為Person的類,其中包含了一個say_hello方法用于打招呼指厌。然后刊愚,我們創(chuàng)建了一個Person對象,并使用weakref.ref函數(shù)創(chuàng)建了一個弱引用ref踩验。

我們可以通過弱引用ref訪問原始的Person對象百拓,并調(diào)用其方法。當(dāng)我們釋放原始對象的引用晰甚,并且沒有其他強引用指向該對象時衙传,弱引用將無法訪問原始對象。

這只是使用Python標(biāo)準(zhǔn)庫處理弱引用的一個簡單示例厕九。根據(jù)實際需求蓖捶,您可以使用weakref模塊進行更復(fù)雜的弱引用操作,如創(chuàng)建弱引用字典扁远、監(jiān)聽對象的銷毀事件等俊鱼。

用于操作列表的工具:魔法書包

想象你有一個魔法書包,里面裝著各種各樣的工具書畅买,無論你需要什么并闲,只要從書包里一翻就能找到。Python的列表工具就是這樣一個魔法書包谷羞,它提供了一系列方便你操作列表的函數(shù)和方法帝火,讓你能輕松應(yīng)對各種數(shù)據(jù)集合的需求。

比如itertools是 Python 標(biāo)準(zhǔn)庫中的一個模塊湃缎,提供了許多用于迭代器和迭代工具的函數(shù)犀填。這些函數(shù)可以用來處理和操作可迭代對象,從而簡化代碼開發(fā)過程嗓违。

以下是一些常用的itertools函數(shù)和它們的用法:

  1. count(start=0, step=1):生成一個無限序列九巡,從指定的起始值開始卫病,以指定的步長遞增芜壁。例如:
from itertools import count

for i in count(start=1, step=2):
    print(i)

這個例子會無限地打印奇數(shù)(從1開始绣的,每次遞增2)盈滴。
注意:慎重執(zhí)行上面代碼,如果執(zhí)行了撒汉,可以使用 ctrl + c 強制停止制恍。

  1. cycle(iterable):對一個可迭代對象進行循環(huán)迭代。例如:
from itertools import cycle

my_list = [1, 2, 3]
for item in cycle(my_list):
    print(item)

這個例子會無限循環(huán)地打印列表 [1, 2, 3] 中的元素神凑。

  1. repeat(element, times=None):重復(fù)一個元素指定的次數(shù)净神,如果沒有指定次數(shù),則無限重復(fù)溉委。例如:
from itertools import repeat

for i in repeat('Hello', 3):
    print(i)

這個例子會打印出三次 'Hello'鹃唯。

  1. chain(*iterables):將多個可迭代對象連接在一起,形成一個更長的迭代器瓣喊。例如:
from itertools import chain

my_list1 = [1, 2, 3]
my_list2 = [4, 5, 6]
for item in chain(my_list1, my_list2):
    print(item)

這個例子會打印整個列表 [1,2,3,4,5,6]坡慌。

  1. combinations(iterable, r):生成一個可迭代對象,包含給定可迭代對象中所有長度為r的組合藻三。
from itertools import combinations

my_list = [1, 2, 3, 4]
my_combinations = combinations(my_list, 2)
for combination in my_combinations:
    print(combination)

這個例子會打印出所有長度為2的組合洪橘,例如 (1, 2)(1, 3) 等等棵帽。

這只是itertools模塊的一小部分功能熄求。您可以根據(jù)需要使用其他函數(shù)和組合這些函數(shù)來解決實際問題。

十進制浮點運算:精確的計算機

當(dāng)你去商店買東西逗概,找零時你肯定希望每一分錢都算得精確弟晚。在計算機世界里,十進制浮點運算就是確保你在處理金錢或需要高精度的計算時逾苫,每一位都準(zhǔn)確無誤卿城。

關(guān)于十進制浮點運算,Python提供了decimal模塊铅搓,用于進行精確的十進制浮點運算瑟押。與使用內(nèi)置的浮點數(shù)類型(如float)相比,decimal模塊可以避免浮點數(shù)精度誤差星掰,并進行更加準(zhǔn)確的計算多望。

以下是一個使用decimal模塊進行十進制浮點運算的示例:

from decimal import Decimal

# 創(chuàng)建Decimal對象并進行運算
a = Decimal('0.1')
b = Decimal('0.2')
c = a + b

# 打印結(jié)果
print(c)  # 輸出: 0.3

# 比較Decimal對象
if c == Decimal('0.3'):
    print("c 等于 0.3") # 輸出: c 等于 0.3

在這個示例中,我們使用Decimal對象創(chuàng)建了表示0.1和0.2的十進制數(shù)蹋偏,并進行了加法運算便斥。由于Decimal對象在內(nèi)部以十進制數(shù)表示,所以可以避免浮點數(shù)精度問題威始,得到精確的結(jié)果0.3。

看完以上這些像街,是不是覺得Python的瑞士軍刀既神奇又實用呢黎棠?別忘了晋渺,這只是冰山一角,Python的世界還有無數(shù)神秘和樂趣等你去探索脓斩。所以木西,拿起你的瑞士軍刀,讓我們一起冒險去吧随静!

歡迎關(guān)注微信公眾號【千練極客】八千,盡享更多干貨文章!

歡迎關(guān)注微信公眾號【千練極客】燎猛,盡享更多干貨文章恋捆!

歡迎關(guān)注微信公眾號【千練極客】,盡享更多干貨文章重绷!

本文由博客一文多發(fā)平臺 OpenWrite 發(fā)布沸停!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市昭卓,隨后出現(xiàn)的幾起案子愤钾,更是在濱河造成了極大的恐慌,老刑警劉巖候醒,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件能颁,死亡現(xiàn)場離奇詭異,居然都是意外死亡倒淫,警方通過查閱死者的電腦和手機劲装,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來昌简,“玉大人占业,你說我怎么就攤上這事〈渴辏” “怎么了谦疾?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長犬金。 經(jīng)常有香客問我念恍,道長,這世上最難降的妖魔是什么晚顷? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任峰伙,我火速辦了婚禮,結(jié)果婚禮上该默,老公的妹妹穿的比我還像新娘瞳氓。我一直安慰自己,他們只是感情好栓袖,可當(dāng)我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布匣摘。 她就那樣靜靜地躺著店诗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪音榜。 梳的紋絲不亂的頭發(fā)上庞瘸,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機與錄音赠叼,去河邊找鬼擦囊。 笑死,一個胖子當(dāng)著我的面吹牛嘴办,可吹牛的內(nèi)容都是我干的瞬场。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼户辞,長吁一口氣:“原來是場噩夢啊……” “哼泌类!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起底燎,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤刃榨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后双仍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體枢希,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年朱沃,在試婚紗的時候發(fā)現(xiàn)自己被綠了苞轿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡逗物,死狀恐怖搬卒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情翎卓,我是刑警寧澤契邀,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站失暴,受9級特大地震影響坯门,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜逗扒,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一古戴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧矩肩,春花似錦现恼、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽痹升。三九已至建炫,卻和暖如春畦韭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背肛跌。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工艺配, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人衍慎。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓转唉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親稳捆。 傳聞我的和親對象是個殘疾皇子赠法,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容