中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python中常見的陷阱有哪些

發布時間:2020-08-04 09:49:54 來源:億速云 閱讀:205 作者:清晨 欄目:編程語言

這篇文章主要介紹Python中常見的陷阱有哪些,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

Python的編碼規范基本遵從PEP8準則,使用四個空格作為縮進,避免空格鍵和tab鍵混用,善于添加注釋,當一行代碼寫不下時,右括號要放到行首,和變量對齊,導入順序 標準庫、第三方、本地庫,各組之間有個空行隔開。通常,Python 旨在成為一門簡潔一致的語言,避免發生意外。然而,有些情況可能會給新手們造成困惑。

在這些情況中,有一些雖是有意為之,但還是有潛在風險。還有一些則可以說是語言設計缺陷了。總之,下面列出的這些情況都是些乍一看很不好理解的行為,不過一旦您了解了這些奇怪行為背后的機理,也就基本上能理解了。

可變默認參數

似乎每個 Python 新手都會感到驚訝的一點是 Python 在函數定義中對待可變默認參數的方法。

您所寫的

def append_to(element, to=[]):
    to.append(element)
    return to

您可能期待的結果

my_list = append_to(12)
print my_list

my_other_list = append_to(42)
print my_other_list

函數每次被調用時,如果不提供第二個參數,就創建一個新的列表。所以結果就應該是:

[12]
[42]

實際上的結果

[12]
[12, 42]

一旦 完成了函數定義,一個新的列表就創建出來了,而且在隨后的每一次函數調用中被使用的都是這個列表。

一旦 完成了函數定義,Python 的默認參數就被賦值了,而且在隨后的每一次函數調用中都不會再被默認值重復賦值(就像是在,嗯,Ruby 里那樣)。這就意味著如果您使用了一個可變默認參數,并且改變了它,您也會且 將會 在未來的所有函數調用中改變這同一個參數對象。

您實際上應該做的

使用一個默認值來表示我們并不想給這個參數賦值,從而每次在函數被調用時我們都創建一個新的對象。(None 作為默認值通常是個好選擇)。

def append_to(element, to=None):
    if to is None:
        to = []
    to.append(element)
    return to

可別忘了,您所傳遞的第二個參數仍應該是個 列表 對象。

利用好『缺陷』

有時你可以專門 利用(或者說特地使用)這種行為來維護函數調用間的狀態。這通常用于編寫緩存函數。

延遲綁定閉包

另一個常見的困惑是 Python 在閉包(或在周圍全局作用域)中綁定變量的方式。

當你寫下

def create_multipliers():
    return [lambda x : i * x for i in range(5)]

你期望發生

for multiplier in create_multipliers():
    print multiplier(2)

一個包含五個函數的列表,每個函數有它們自己的封閉變量 i 乘以它們的參數,得到:

0
2
4
6
8

而事實是:

8
8
8
8
8

五個函數被創建了,它們全都用 4 乘以 x 。

Python 的閉包是 延遲綁定的 。 這意味著閉包中用到的變量的值,是在內部函數被調用時查詢得到的。

這里,不論 任何 返回的函數是如何被調用的, i 取的是調用時周圍作用域里的值。 當循環完成時, i 的值最終變成了 4。

關于這個陷阱有一個普遍嚴重的誤解,它被認為只針對 Python 的 閉包 lambda 定義方式。 事實上,由 lambda 表達式創建的函數并沒什么特別,同樣的問題也出現在使用普通的 def 上:

def create_multipliers():
    multipliers = []

    for i in range(5):
        def multiplier(x):
            return i * x
        multipliers.append(multiplier)

    return multipliers

以上正確的做法應該是:

def create_multipliers():
    return [lambda x, i=i : i * x for i in range(5)]

或者,使用 functools.partial 函數:

from functools import partial
from operator import mul

def create_multipliers():
    return [partial(mul, i) for i in range(5)]

有時你就想要閉包有如此表現,延遲綁定在很多情況下是一個很贊的特性。不幸的是,循環創建獨立函數是一種會使它們出差錯的情況。

字節碼(.pyc)文件無處不在!

默認情況下,當你直接執行 Python 腳本文件時,Python 解釋器會自動將該文件的字節碼版本寫入同目錄下。 比如, module.pyc。

這些 .pyc 文件不應該被納入源代碼倉庫。

理論上,出于性能原因,此行為默認為開啟。 沒有這些字節碼文件, Python 會在每次加載文件時重新生成字節碼文件。

禁用字節碼(.pyc)文件

幸運的是,生成字節碼的過程非常快,在開發代碼時不需要擔心。

那些文件很討厭,所以讓我們擺脫他們吧!

$ export PYTHONDONTWRITEBYTECODE=1

使用 $PYTHONDONTWRITEBYTECODE 環境變量來命令 Python 不將這些文件寫入磁盤, 開發環境將會保持整潔和干凈。

我建議在你的 ~/.profile 里設置這個環境變量。

以上是Python中常見的陷阱有哪些的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

永胜县| 普兰店市| 盐城市| 资阳市| 鹤壁市| 子洲县| 深水埗区| 南京市| 永善县| 牡丹江市| 方山县| 乐业县| 喀喇沁旗| 德江县| 富裕县| 海口市| 巴马| 凌源市| 郁南县| 尖扎县| 辽阳县| 安丘市| 阳城县| 乌兰察布市| 金沙县| 东安县| 宝丰县| 万州区| 淄博市| 上虞市| 方山县| 藁城市| 甘洛县| 临邑县| 孙吴县| 娱乐| 阳新县| 扎鲁特旗| 宁南县| 清苑县| 治县。|