成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Python也許很友好,但它也容易弄得一團(tuán)槽

譯文 精選
開(kāi)發(fā)
直到出現(xiàn)問(wèn)題前,Python對(duì)初學(xué)者都是友好的

  作者 | Ari Joury

  譯者 | 王德朕

  審校 | Noe

  無(wú)論是行業(yè)領(lǐng)袖還是學(xué)術(shù)研究人員,都吹捧Python是編程新手最好的語(yǔ)言之一。他們沒(méi)有錯(cuò),但這并不意味著Python不會(huì)讓編程新手們感到困惑。

  以動(dòng)態(tài)類型為例,看起來(lái)令人驚訝,Python 可以自己計(jì)算出變量可能獲得的值類型,而且不需要浪費(fèi)一行代碼來(lái)聲明類型,這樣更快。

  一開(kāi)始是這樣的,然后你在某一行搞砸了,繼而導(dǎo)致你的整個(gè)項(xiàng)目在運(yùn)行之前就崩潰了。

  公平地說(shuō),其它語(yǔ)言許多都使用動(dòng)態(tài)類型,但對(duì)于 Python 來(lái)說(shuō),這僅僅是一個(gè)糟糕清單的開(kāi)始。

隱式聲明變量會(huì)使得代碼變得一團(tuán)糟

  幾年前,當(dāng)我開(kāi)始攻讀博士學(xué)位時(shí),我想進(jìn)一步開(kāi)發(fā)一個(gè)由同事編寫(xiě)的現(xiàn)有軟件,我了解它的基本原理,甚至我的同事寫(xiě)了一篇關(guān)于它的文檔。

  但我仍然需要閱讀成千上萬(wàn)行的Python代碼,以確保我知道每部分代碼做了什么,從而可以把我想到的新功能放在那里,這就是問(wèn)題所在......

  整個(gè)代碼中到處都是未被聲明的變量,為了理解每個(gè)變量的用途,我必須在整個(gè)文件中搜索它,更常見(jiàn)的是在整個(gè)項(xiàng)目中搜索它。

  還有一個(gè)復(fù)雜的情況,變量通常在函數(shù)內(nèi)部被調(diào)用,但是當(dāng)函數(shù)被調(diào)用時(shí),又會(huì)有其他的東西被調(diào)用……還有一個(gè)情況,一個(gè)變量可以與一個(gè)類交織在一起,這個(gè)類與另一個(gè)類的另一個(gè)變量相關(guān)聯(lián),而另一個(gè)類又影響著一個(gè)完全不同的類……你明白了吧。

  有這種經(jīng)歷的不止我一個(gè),《Python之禪》中明確表示,顯式要比隱式好,但是在Python中做隱式變量太容易了,特別是在大型項(xiàng)目中,很快就會(huì)遇到麻煩。

可變類型無(wú)處不在--甚至在函數(shù)中也是如此

  在Python中,你可以通過(guò)提供默認(rèn)值來(lái)定義具有可選參數(shù)的函數(shù),不必再顯式聲明,像這樣:

def add_five(a, b=0):
  return a + b + 5

  我知道這是個(gè)鬧著玩的例子,但是你現(xiàn)在可以用一個(gè)或者兩個(gè)參數(shù)來(lái)調(diào)用這個(gè)函數(shù),它還是可以工作的:

add_five(3) # 返回 8
add_five(3,4) # 返回 12

  它能運(yùn)行,是因?yàn)楸磉_(dá)式 b = 0將 b 定義為一個(gè)整數(shù),而整數(shù)是不可變的:

def add_element(list=[]):
  list.append("foo")
  return list
add_element() # 返回 ["foo"],符合預(yù)期

  到目前為止,一切正常,但是如果再次執(zhí)行它會(huì)發(fā)生什么?

add_element() # returns ["foo", "foo"]! wtf!

       因?yàn)閰?shù)是一個(gè)列表,即列表 ["foo"] 已經(jīng)存在,Python 只是把它的東西附加到那個(gè)列表中,這樣做是因?yàn)榱斜砼c整數(shù)不同,列表是可變的類型。

       常言道: “瘋狂就是一再重復(fù)相同的事情,卻期望得到不同的結(jié)果”(這句話常常被誤認(rèn)為是阿爾伯特· 愛(ài)因斯坦說(shuō)的)。也可以說(shuō),Python 加上可選參數(shù),加上可變對(duì)象簡(jiǎn)直是瘋了。

類變量也不安全

  如果你認(rèn)為這些問(wèn)題僅限于可變對(duì)象作為可選參數(shù)的情況,那就錯(cuò)了。

  如果你進(jìn)行面向?qū)ο缶幊蹋◣缀跛腥硕际沁@樣),那么類在Python代碼中無(wú)處不在,有史以來(lái),類最有用的特性之一是——繼承。

  這只是一個(gè)花哨的說(shuō)法,如果你有一個(gè)具有某些屬性的父類,你可以創(chuàng)建一個(gè)子類繼承其屬性,像這樣:

class parent(object):
  x = 1
class firstchild(parent):
  pass
class secondchild(parent):
  pass
print(parent.x, firstchild.x, secondchild.x) # 返回 1 1 1

  這不是一個(gè)特別好的例子,所以不要將其復(fù)制到你的代碼項(xiàng)目中。關(guān)鍵是,子類繼承了x=1,因此我們可以調(diào)用它,并得到與父類相同的結(jié)果。

  而且,如果我們改變了一個(gè)子類的x屬性,它應(yīng)該只改變那個(gè)子類。就像你在青少年時(shí)期染了頭發(fā),它不會(huì)改變你父母或你兄弟姐妹的頭發(fā),這樣就可以了。

firstchild.x = 2
print(parent.x, firstchild.x, secondchild.x) # 返回 1 2 1

  你小時(shí)候媽媽染頭發(fā)的時(shí)候發(fā)生了什么? 你的頭發(fā)沒(méi)變,對(duì)吧?

parent.x = 3
print(parent.x, firstchild.x, secondchild.x) # 返回3 2 3

       這是因?yàn)?Python 的方法解析順序,只要沒(méi)有特殊的說(shuō)明,子類繼承了父類的一切,所以,在Python世界中,如果你不提前抗議,媽媽在做她的頭發(fā)時(shí)就會(huì)給你染發(fā)。

作用域有時(shí)候會(huì)反過(guò)來(lái)

  接下來(lái)這個(gè)關(guān)卡已經(jīng)絆倒我很多次了。

  在 Python 中,如果在函數(shù)內(nèi)部定義變量,那么這個(gè)變量不會(huì)在函數(shù)外部工作,有人說(shuō)這超出了作用域:

def myfunction(number):
  basenumber = 2
  return basenumber*number
basenumber
## Oh no! This is the error:
# Traceback (most recent call last):
# File "", line 1, in
# NameError: name 'basenumber' is not defined

  這應(yīng)該是相當(dāng)直觀的(不,我沒(méi)有在這一點(diǎn)上絆倒)。

  那反過(guò)來(lái)呢?我的意思是,如果我在函數(shù)外面定義一個(gè)變量,然后在函數(shù)內(nèi)部引用它,會(huì)怎么樣?

x = 2
def add_5():
  x = x + 5
  print(x)
add_5()
## Oh dear...
# Traceback (most recent call last):
# File "", line 1, in
# File "", line 2, in add_y
# UnboundLocalError: local variable 'x' referenced before assignment

       奇怪吧?如果阿爾伯特生活在一個(gè)有樹(shù)的世界里,并且阿爾伯特生活在一所房子里,那么阿爾伯特想必是知道樹(shù)是什么樣子的?(樹(shù)是x,阿爾伯特的房子是add_ 5(),阿爾伯特是5……)

  我曾多次碰到這個(gè)問(wèn)題,在一個(gè)類中,定義被另一個(gè)類調(diào)用的函數(shù)時(shí),我花了很長(zhǎng)時(shí)間才找到問(wèn)題的根源。

  這背后的想法是,函數(shù)內(nèi)部的x與外部的x是不同的,所以你不能就這樣改變它。就像如果阿爾伯特只是夢(mèng)想著把樹(shù)變成橙色,那當(dāng)然不會(huì)讓樹(shù)實(shí)際變成橙色。

  幸運(yùn)的是,這個(gè)問(wèn)題有一個(gè)簡(jiǎn)單的解決方案,只要在 x 之前添加一個(gè) global!

x = 2
def add_5():
  global x
  x = x + 5
print(x)
add_5() # works!

       因此,如果你認(rèn)為作用域只能保護(hù)函數(shù)內(nèi)部的變量不受外部世界的影響,那么請(qǐng)?jiān)倏紤]一下。在 Python 中,外部世界受到局部變量的保護(hù),就像阿爾伯特不能用他思想的力量把樹(shù)涂成橙色一樣。

在迭代列表時(shí)修改列表

  我自己也遇到過(guò)幾次這樣的胡說(shuō)八道。

  想想這個(gè):

mynumbers = [x for x in range(10)]
# this is [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for x in range(len(mynumbers)):
  if mynumbers[x]%3 == 0:
  mynumbers.remove(mynumbers[x])

## Ew!
# Traceback (most recent call last):
# File "", line 2, in
# IndexError: list index out of range

  這個(gè)循環(huán)不起作用,因?yàn)樗扛粢欢螘r(shí)間就會(huì)刪除列表中的一個(gè)元素。因此,列表的末端會(huì)向前移動(dòng),那么就不可能到達(dá)10號(hào)元素了,因?yàn)樗呀?jīng)不在那里了!

  一個(gè)簡(jiǎn)單但方便的解決方案,為所有要?jiǎng)h除的元素分配一個(gè)不實(shí)用的值,然后在下一步中刪除它們。

  但有一個(gè)更好的解決辦法:

mynumbers = [x for x in range(10) if x%3 != 0]
# that's what we wanted! [1, 2, 4, 5, 7, 8]

  就一行代碼!

  注意,我們已經(jīng)在上面的案例中,使用了 Python 列表解析式來(lái)調(diào)用列表。

      它是方括號(hào)[] 中的表達(dá)式,是循環(huán)的簡(jiǎn)寫(xiě)形式,列表解析式通常比常規(guī)循環(huán)快一點(diǎn),如果你處理的是大型數(shù)據(jù)集,這很酷。

  在這里,我們只是添加了一個(gè) if 子句 來(lái)告訴列表解析式,它不應(yīng)該包含被3整除的數(shù)字。

       與上面描述的一些現(xiàn)象不同,即使初學(xué)者一開(kāi)始可能會(huì)在這個(gè)這問(wèn)題上磕磕絆絆,列表解析也不是 Python 糟糕的設(shè)計(jì),而是 Python 的天才設(shè)計(jì)。

地平線上的一些光亮

      在過(guò)去,當(dāng)遇到與 Python 相關(guān)的問(wèn)題時(shí),編碼并不是唯一的痛苦。Python的執(zhí)行速度也曾經(jīng)慢得令人難以置信,比大多數(shù)語(yǔ)言都慢2到10倍。現(xiàn)在這種情況已經(jīng)好了很多,例如,Numpy 包在處理列表、矩陣等等方面非常快。

  使用Python,多進(jìn)程也變得更加容易。這可以讓你使用所有的2個(gè)、16個(gè)或多個(gè)核心的計(jì)算機(jī),而不是只有一個(gè)。我已經(jīng)在20個(gè)核心上運(yùn)行過(guò),它已經(jīng)為我節(jié)省了數(shù)周的計(jì)算時(shí)間。

       此外,隨著機(jī)器學(xué)習(xí)在過(guò)去幾年中取得進(jìn)展,Python 已經(jīng)表明,它還有很長(zhǎng)的路要走。像 Pytorch 和 Tensorflow 這樣的軟件包使得機(jī)器學(xué)習(xí)變得非常容易,而其他語(yǔ)言正在努力跟上這一步。

  這些年來(lái) Python 已經(jīng)變得更好了,然而,這一事實(shí)并不能保證一個(gè)美好的未來(lái),Python仍然不是傻瓜式的,請(qǐng)謹(jǐn)慎地使用它。

譯者介紹

  王德朕,51CTO社區(qū)編輯,10年互聯(lián)網(wǎng)產(chǎn)研經(jīng)驗(yàn),6年IT教培行業(yè)經(jīng)驗(yàn)。原K12教育上市公司產(chǎn)品經(jīng)理,技術(shù)博客專家,藍(lán)橋簽約作者,《滾雪球?qū)WPython》專欄作者,《爬蟲(chóng)100例》專欄特約作者,78技術(shù)人社區(qū)發(fā)起者。

  原文標(biāo)題:Python may be easy but it’s a goddamn mess

  鏈接:https://thenextweb.com/news/python-may-be-easy-but-its-a-mess

責(zé)任編輯:張潔
相關(guān)推薦

2009-12-16 09:52:15

Linux操作系統(tǒng)

2019-07-08 11:25:14

云計(jì)算工具Kubernetes

2011-07-04 10:08:59

LinuxARM

2021-02-24 15:09:51

編程技能開(kāi)發(fā)

2019-03-11 15:26:26

HTTPSHTTP密鑰

2019-10-25 09:35:58

HTTPSHTTP通信

2019-11-13 09:08:50

HTTPS安全加密算法

2024-12-03 15:42:13

命令模式代碼

2024-06-17 10:30:38

運(yùn)維IP地址網(wǎng)絡(luò)

2022-08-26 09:02:57

代碼庫(kù)編程語(yǔ)言

2011-12-29 16:37:21

筆記本評(píng)測(cè)

2019-11-15 09:26:36

OAuthWeb系統(tǒng)

2011-12-21 17:04:53

云計(jì)算

2024-08-23 15:02:23

2019-11-05 09:20:06

SQLiteLinux

2022-01-04 10:19:23

架構(gòu)運(yùn)維技術(shù)

2012-02-29 08:54:54

甲骨文云計(jì)算

2018-07-04 11:01:48

2011-12-29 09:03:30

云計(jì)算

2023-05-09 12:27:52

亞馬遜微服務(wù)重構(gòu)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 亚洲精品一区二三区不卡 | 九九热国产精品视频 | 国产成人综合在线 | 欧美成人a∨高清免费观看 色999日韩 | av一级在线观看 | 久久久久成人精品亚洲国产 | 国产成人网 | 亚洲播放一区 | 午夜视频网站 | 欧美国产日韩在线观看 | 天天综合国产 | 日韩图区 | 香蕉一区 | 一区二区三区中文 | 韩国av一区二区 | 在线91| 久久99精品久久 | 男女黄网站 | 国产韩国精品一区二区三区 | 亚洲国产精品久久久久 | 天天操天天拍 | 欧美午夜精品理论片a级按摩 | 国产高清在线精品一区二区三区 | 欧美激情久久久 | 欧美视频在线看 | 国产成人综合网 | 久久久久久久久久久久久久av | 99re视频在线观看 | 亚洲欧美在线视频 | av永久| .国产精品成人自产拍在线观看6 | 成人免费视频播放 | 精品国产乱码久久久久久蜜柚 | 91av视频在线播放 | 欧美日韩精品一区二区三区四区 | 欧美一区二区在线播放 | 中文字幕第7页 | 久久精品成人 | 国产欧美视频一区二区三区 | 日本不卡免费新一二三区 | 国产欧美日韩久久久 |