chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀(guān)看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何讓你的Python編程中不出現(xiàn)反模式?避免初學(xué)Python常見(jiàn)的錯(cuò)誤

馬哥Linux運(yùn)維 ? 來(lái)源:未知 ? 作者:易水寒 ? 2018-09-24 10:38 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

這篇文章收集了我在Python新手開(kāi)發(fā)者寫(xiě)的代碼中所見(jiàn)到的不規(guī)范但偶爾又很微妙的問(wèn)題。

本文的目的是為了幫助那些新手開(kāi)發(fā)者渡過(guò)寫(xiě)出丑陋的Python代碼的階段。

對(duì)于那些新手開(kāi)發(fā)者,總有一些使用反模式的理由,我已經(jīng)嘗試在可能的地方給出了這些理由。

但通常這些反模式會(huì)造成代碼缺乏可讀性、更容易出bug且不符合Python的代碼風(fēng)格。

迭代

range的使用

Python編程新手喜歡使用range來(lái)實(shí)現(xiàn)簡(jiǎn)單的迭代,在迭代器的長(zhǎng)度范圍內(nèi)來(lái)獲取迭代器中的每一個(gè)元素:

應(yīng)該牢記:range并不是為了實(shí)現(xiàn)序列簡(jiǎn)單的迭代。相比那些用數(shù)字定義的for循環(huán),雖然用range實(shí)現(xiàn)的for循環(huán)顯得很自然,但是用在序列的迭代上卻容易出bug,而且不如直接構(gòu)造迭代器看上去清晰:

range的濫用容易造成意外的大小差一(off-by-one)錯(cuò)誤,這通常是由于編程新手忘記了range生成的對(duì)象包括range的第一個(gè)參數(shù)而不包括第二個(gè),類(lèi)似于java中的substring和其他眾多這種類(lèi)型的函數(shù)。那些認(rèn)為沒(méi)有超出序列結(jié)尾的編程新手將會(huì)制造出bug:

不恰當(dāng)?shù)厥褂胷ange的常見(jiàn)理由:1.需要在循環(huán)中使用索引。

這并不是一個(gè)合理的理由,可以用以下方式代替使用索引:

2.需要同時(shí)迭代兩個(gè)循環(huán),用同一個(gè)索引來(lái)獲取兩個(gè)值。

這種情況下,可以用zip來(lái)實(shí)現(xiàn):

3.需要迭代序列的一部分。在這種情況下,僅需要迭代序列切片就可以實(shí)現(xiàn),注意添加必要的注釋注明用意:

有一個(gè)例外:

當(dāng)你迭代一個(gè)很大的序列時(shí),切片操作引起的開(kāi)銷(xiāo)就比較大。

如果序列只有10個(gè)元素,就沒(méi)有什么問(wèn)題;但是如果有1000萬(wàn)個(gè)元素時(shí),或者在一個(gè)性能敏感的內(nèi)循環(huán)中進(jìn)行切片操作時(shí),開(kāi)銷(xiāo)就變得非常重要了。

這種情況下可以考慮使用xrange代替range [1]。

在用來(lái)迭代序列之外,range的一個(gè)重要用法是當(dāng)你真正想要生成一個(gè)數(shù)字序列而不是用來(lái)生成索引:

正確使用列表解析

如果你有像這樣的一個(gè)循環(huán):

你可以使用列表解析來(lái)重寫(xiě):

為什么要這么做?

一方面你避免了正確初始化列表可能帶來(lái)的錯(cuò)誤,另一方面,這樣寫(xiě)代碼讓看起來(lái)很干凈,整潔。

對(duì)于那些有函數(shù)式編程背景的人來(lái)說(shuō),使用map函數(shù)可能感覺(jué)更熟悉,但是在我看來(lái)這種做法不太Python化。

其他的一些不使用列表解析的常見(jiàn)理由:

1. 需要循環(huán)嵌套。

這個(gè)時(shí)候你可以嵌套整個(gè)列表解析,或者在列表解析中多行使用循環(huán):

使用列表解析:

注意:在有多個(gè)循環(huán)的列表解析中,循環(huán)有同樣的順序就像你并沒(méi)有使用列表解析一樣。

2. 你在循環(huán)內(nèi)部需要一個(gè)條件判斷。

你只需要把這個(gè)條件判斷添加到列表解析中去:

一個(gè)不使用列表解析的合理的理由是你在列表解析里不能使用異常處理。

如果迭代中一些元素可能引起異常,你需要在列表解析中通過(guò)函數(shù)調(diào)用轉(zhuǎn)移可能的異常處理,或者干脆不使用列表解析。

性能缺陷

在線(xiàn)性時(shí)間內(nèi)檢查內(nèi)容

在語(yǔ)法上,檢查list或者set/dict中是否包含某個(gè)元素表面上看起來(lái)沒(méi)什么區(qū)別,但是表面之下卻是截然不同的。

如果你需要重復(fù)檢查某個(gè)數(shù)據(jù)結(jié)構(gòu)里是否包含某個(gè)元素,最好使用set來(lái)代替list。(如果你想把一個(gè)值和要檢查的元素聯(lián)系起來(lái),可以使用dict;這樣同樣可以實(shí)現(xiàn)常數(shù)檢查時(shí)間。)

Python中set的元素和dict的鍵值是可哈希的,因此查找起來(lái)時(shí)間復(fù)雜度為O(1)。

應(yīng)該記?。?/p>

創(chuàng)建set引入的是一次性開(kāi)銷(xiāo),創(chuàng)建過(guò)程將花費(fèi)線(xiàn)性時(shí)間即使成員檢查花費(fèi)常數(shù)時(shí)間。

因此如果你需要在循環(huán)里檢查成員,最好先花時(shí)間創(chuàng)建set,因?yàn)槟阒恍枰獎(jiǎng)?chuàng)建一次。

變量泄露

循環(huán)

通常說(shuō)來(lái),在Python中,一個(gè)變量的作用域比你在其他語(yǔ)言里期望的要寬。

例如:在Java中下面的代碼將不能通過(guò)編譯:

然而在Python中,同樣的代碼總會(huì)順利執(zhí)行且得到意料中的結(jié)果:

這段代碼將會(huì)正常運(yùn)行,除非子y為空的情況下,此時(shí),循環(huán)永遠(yuǎn)不會(huì)執(zhí)行,而且processList函數(shù)的調(diào)用將會(huì)拋出NameError異常,因?yàn)閕dx沒(méi)有定義。

如果你使用Pylint代碼檢查工具,將會(huì)警告:使用可能沒(méi)有定義的變量idx。

解決辦法永遠(yuǎn)是顯然的,可以在循環(huán)之前設(shè)置idx為一些特殊的值,這樣你就知道如果循環(huán)永遠(yuǎn)沒(méi)有執(zhí)行的時(shí)候你將要尋找什么。

這種模式叫做哨兵模式。那么什么值可以用來(lái)作為哨兵呢?

C語(yǔ)言時(shí)代或者更早,當(dāng)int統(tǒng)治編程世界的時(shí)候,對(duì)于需要返回一個(gè)期望的錯(cuò)誤結(jié)果的函數(shù)來(lái)說(shuō)為通用的模式為返回-1。

例如,當(dāng)你想要返回列表中某一元素的索引值:

通常情況下,在Python里None是一個(gè)比較好的哨兵值,即使它不是一貫地被Python標(biāo)準(zhǔn)類(lèi)型使用(例如:str.find [2])

外作用域

Python程序員新手經(jīng)常喜歡把所有東西放到所謂的外作用域——python文件中不被代碼塊(例如函數(shù)或者類(lèi))包含的部分。

外作用域相當(dāng)于全局命名空間;為了這部分的討論,你應(yīng)該假設(shè)全局作用域的內(nèi)容在單個(gè)Python文件的任何地方都是可以訪(fǎng)問(wèn)的。

對(duì)于定義整個(gè)模塊都需要去訪(fǎng)問(wèn)的在文件頂部聲明的常量,外作用域顯得非常強(qiáng)大。

給外作用域中的任何變量使用有特色的名字是明智的做法,例如,使用IN_ALL_CAPS 這個(gè)常量名。 這將不容易造成如下bug:

如果你看的近一點(diǎn),你將看到print_file函數(shù)的定義中用filenam命名參數(shù)名,但是函數(shù)體卻引用的卻是filename。

然而,這個(gè)程序仍然可以運(yùn)行得很好。

為什么呢?

在print_file函數(shù)里,當(dāng)一個(gè)局部變量filename沒(méi)有被找到時(shí),下一步是在全局作用域中去尋找。

由于print_file的調(diào)用在外作用域中(即使有縮進(jìn)),這里聲明的filename對(duì)于print_file函數(shù)是可見(jiàn)的。

那么如何避免這樣的錯(cuò)誤呢?

首先,在外作用域中不是IN_ALL_CAPS這樣的全局變量就不要設(shè)置任何值[3]。

參數(shù)解析最好交給main函數(shù),因此函數(shù)中任何內(nèi)部變量不在外作用域中存活。

這也提醒人們關(guān)注全局關(guān)鍵字global。如果你只是讀取全局變量的值,你就不需要全局關(guān)鍵字global。

你只有在想要改變?nèi)肿兞棵玫膶?duì)象時(shí)有使用global關(guān)鍵字的必要。

代碼風(fēng)格

向PEP8致敬

PEP 8是Python代碼的通用風(fēng)格指南,你應(yīng)該牢記在心并且盡可能去遵循它,盡管一些人有充分的理由不同意其中一些細(xì)小的風(fēng)格,例如縮進(jìn)的空格個(gè)數(shù)或使用空行。

如果你不遵循PEP8,你應(yīng)該有除“我只是不喜歡那樣的風(fēng)格”之外更好的理由。下邊的風(fēng)格指南都是從PEP8中摘取的,似乎是編程者經(jīng)常需要牢記的。

測(cè)試是否為空

如果你要檢查一個(gè)容器類(lèi)型(例如:列表,詞典,集合)是否為空,只需要簡(jiǎn)單測(cè)試它而不是使用類(lèi)似檢查len(x)>0這樣的方法:

如果你想在其他地方保存positive_numbers是否為空的結(jié)果,可以使用bool(positive_number)作為結(jié)果保存;bool用來(lái)判斷if條件判斷語(yǔ)句的真值。

測(cè)試是否為None

如前面所提到,None可以作為一個(gè)很好的哨兵值。那么如何檢查它呢?

如果你明確的想要測(cè)試None,而不只是測(cè)試其他一些值為False的項(xiàng)(如空容器或者0),可以使用:

如果你使用None作為哨兵,這也是Python風(fēng)格所期望的模式,例如在你想要區(qū)分None和0的時(shí)候。

如果你只是測(cè)試變量是否為一些有用的值,一個(gè)簡(jiǎn)單的if模式通常就夠用了:

例如:如果期望x是一個(gè)容器類(lèi)型,但是x可能作另一個(gè)函數(shù)的返回結(jié)果值變?yōu)镹one,你應(yīng)該立即考慮到這種情況。你需要留意是否改變了傳給x的值,否則可能你認(rèn)為T(mén)rue或0. 0是個(gè)有用的值,程序卻不會(huì)按照你想要的方式執(zhí)行。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀(guān)點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 編程
    +關(guān)注

    關(guān)注

    89

    文章

    3704

    瀏覽量

    96278
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4922

    瀏覽量

    72255
  • Range
    +關(guān)注

    關(guān)注

    0

    文章

    9

    瀏覽量

    11418
  • python
    +關(guān)注

    關(guān)注

    56

    文章

    4848

    瀏覽量

    88974

原文標(biāo)題:Python編程中的反模式

文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    代碼又雙叕錯(cuò)誤,python17個(gè)常見(jiàn)失誤不僅新手會(huì)犯,也可能會(huì)

    對(duì)初學(xué)者來(lái)說(shuō),想要弄懂Python的某些錯(cuò)誤信息還是有困難的,下面羅列了一些常見(jiàn)的運(yùn)行時(shí)錯(cuò)誤
    的頭像 發(fā)表于 09-19 11:08 ?3778次閱讀

    我沒(méi)學(xué)過(guò)編程,能否學(xué)會(huì)Python

    ?Python是一種計(jì)算機(jī)程序設(shè)計(jì)語(yǔ)言。可能已經(jīng)聽(tīng)說(shuō)過(guò)很多種流行的編程語(yǔ)言,比如非常難學(xué)的C語(yǔ)言,非常流行的Java語(yǔ)言,適合初學(xué)者的Basic語(yǔ)言,適合網(wǎng)頁(yè)
    發(fā)表于 07-14 14:49

    我沒(méi)學(xué)過(guò)編程,能否學(xué)會(huì)Python

    ?Python是一種計(jì)算機(jī)程序設(shè)計(jì)語(yǔ)言。可能已經(jīng)聽(tīng)說(shuō)過(guò)很多種流行的編程語(yǔ)言,比如非常難學(xué)的C語(yǔ)言,非常流行的Java語(yǔ)言,適合初學(xué)者的Basic語(yǔ)言,適合網(wǎng)頁(yè)
    發(fā)表于 07-25 10:21

    Python編程實(shí)用指南

    Python 是一種解釋型、面向?qū)ο?、?dòng)態(tài)數(shù)據(jù)類(lèi)型的高級(jí)程序設(shè)計(jì)語(yǔ)言。通過(guò) Python 編程,我們能夠解決現(xiàn)實(shí)生活的很多任務(wù)。本書(shū)是一本面向?qū)嵺`的
    發(fā)表于 09-27 06:21

    初學(xué)常見(jiàn)Python運(yùn)行錯(cuò)誤及其示例歸納

    對(duì)初學(xué)者來(lái)說(shuō),想要弄懂Python的某些錯(cuò)誤信息還是有困難的,下面羅列了一些常見(jiàn)的運(yùn)行時(shí)錯(cuò)誤: 1.忘記在if, elif, else, f
    發(fā)表于 11-15 13:35 ?2728次閱讀

    Python編程和機(jī)器學(xué)習(xí)編程示范代碼

    機(jī)器學(xué)習(xí)離不開(kāi)Python。所以,全球第一的AI教科書(shū)作者、Google Research總監(jiān)Peter Novig就專(zhuān)門(mén)為初學(xué)者做了一個(gè)關(guān)于Python編程示范操作的GitHub項(xiàng)目
    的頭像 發(fā)表于 12-21 16:49 ?6014次閱讀
    <b class='flag-5'>Python</b><b class='flag-5'>編程</b>和機(jī)器學(xué)習(xí)<b class='flag-5'>編程</b>示范代碼

    Python編程時(shí)常見(jiàn)的3個(gè)錯(cuò)誤

    以下列出了學(xué)習(xí) Python 時(shí)犯的三種錯(cuò)誤: 1.可變數(shù)據(jù)類(lèi)型作為函數(shù)定義的默認(rèn)參數(shù) 2.可變數(shù)據(jù)類(lèi)型作為類(lèi)變量 3. 可變的分配錯(cuò)誤
    發(fā)表于 03-21 11:46 ?1318次閱讀

    Python編程犯的三種錯(cuò)誤,浪費(fèi)一下午時(shí)間

    為了初學(xué) Python 的程序員避免犯同樣的錯(cuò)誤,以下列出了我學(xué)習(xí) Python 時(shí)犯的三種
    發(fā)表于 07-07 08:55 ?6039次閱讀

    新手學(xué)習(xí)Python有哪些常見(jiàn)錯(cuò)誤

    學(xué)習(xí)Python的過(guò)程中發(fā)現(xiàn)一些常見(jiàn)錯(cuò)誤,或許大家也會(huì) 遇到,這里在此總結(jié)如下:
    發(fā)表于 10-30 19:45 ?4次下載

    Python入門(mén)應(yīng)該避免什么樣的錯(cuò)誤

    在分享每個(gè)Python新手應(yīng)該知道的4個(gè)常見(jiàn)錯(cuò)誤之前,請(qǐng)確保您熟悉以下文章的一些Python內(nèi)置功能。
    的頭像 發(fā)表于 04-06 12:03 ?2402次閱讀

    初學(xué)者開(kāi)發(fā)人員都會(huì)犯的7個(gè)Python錯(cuò)誤

    這篇文章主要介紹了七個(gè)初學(xué)者常犯的Python調(diào)試錯(cuò)誤,并告訴大家如何去避免這些錯(cuò)誤。
    的頭像 發(fā)表于 06-23 15:19 ?2949次閱讀
    <b class='flag-5'>初學(xué)</b>者開(kāi)發(fā)人員都會(huì)犯的7個(gè)<b class='flag-5'>Python</b><b class='flag-5'>錯(cuò)誤</b>

    Python新手經(jīng)常會(huì)犯那些錯(cuò)誤

    當(dāng)初學(xué)Python 時(shí),想要弄懂Python錯(cuò)誤信息的含義可能有點(diǎn)復(fù)雜。這里列出了常見(jiàn)的的一些
    發(fā)表于 03-12 16:20 ?16次下載
    <b class='flag-5'>Python</b>新手經(jīng)常會(huì)犯那些<b class='flag-5'>錯(cuò)誤</b>

    Python中有哪些常見(jiàn)錯(cuò)誤和異常

    python常見(jiàn)異常類(lèi)型 在程序運(yùn)行過(guò)程,總會(huì)遇到各種各樣的問(wèn)題和錯(cuò)誤。 有些錯(cuò)誤是我們編寫(xiě)代碼時(shí)自己造成的,比如語(yǔ)法
    的頭像 發(fā)表于 03-04 16:58 ?4610次閱讀

    python運(yùn)行程序出現(xiàn)紅色空白

    類(lèi)型語(yǔ)言,它對(duì)代碼的語(yǔ)法非常嚴(yán)格。如果的代碼存在語(yǔ)法錯(cuò)誤,Python解釋器將無(wú)法正確解析代碼并運(yùn)行。常見(jiàn)的語(yǔ)法錯(cuò)誤包括拼寫(xiě)
    的頭像 發(fā)表于 11-28 15:30 ?2810次閱讀

    對(duì)比Python與Java編程語(yǔ)言

    Python與Java都是目前非常流行的編程語(yǔ)言,它們各有其獨(dú)特的優(yōu)勢(shì)和適用場(chǎng)景。以下是對(duì)這兩種編程語(yǔ)言的對(duì)比: 一、語(yǔ)法和易用性 Python 語(yǔ)法簡(jiǎn)潔,代碼更易讀,非常適合
    的頭像 發(fā)表于 11-15 09:31 ?1809次閱讀