怎麼樣才算是精通 Python?

當初學習 Python 的時候,看見各種招聘要求寫著 「精通 Python 語言」。所以才問了這樣一個問題,求教大家。過去一年多了,收到了很多回答,也看到了很多想法。


你們所說的什麼要怎樣數據分析、爬蟲、Web 等,在我看來那不是精通 Python,而是精通某一領域,拋開 Python 換用另一門語言也可,在我看來,精通 Python 語言大約需要如下這些步驟(個人愚見,不服你奈我何~~~):

------------------------

level 1:了解基本語法

這是最容易的一級,掌握了 Python 的基本語法,可以通過 Python 代碼實現常用的需求,不管代碼質量怎麼樣。這部分內容,可以參考:The Python Tutorial。

------------------------

level 2:熟練使用常用的庫

  • 熟悉常用 standard library 的使用,包括但不限於 copy / json / itertools / collections / hashlib / os / sys 等,這部分內容,可以參考:The Python Standard Library。
  • 熟悉常用的第三方庫,這就根據每個人不同的用法而有所不同了,但是一定要掌握你所常用的那個領域裡的第三方庫。

------------------------

level 3:Pythonic

這一級別比上一級別稍難,但是還是可以輕鬆達到。所謂 Pythonic,就是相比其它語言,Python 可以通過更加優雅的實現方式(不管是語法糖還是什麼),比如(包括但不限於) with、for-else、try-else、yield 等。

另外你還需要掌握這些所謂魔法的實現原理,了解 Python 在語法層面的一些協議,可以自己實現語法糖。如 with 的實現方式(上下文管理器)等。

達到這一級,你的代碼可以看起來很漂亮了。這部分內容,可以參考:

  • The Python Language Reference

  • Python HOWTOs

------------------------

level 4:高級玩法

掌握 Python 的內存機制、GIL 限制等,知道如何改變 Python 的行為,可以輕鬆寫出高效的優質的 Python 代碼,能夠輕鬆分辨不同 Python 代碼的效率並知道如何優化。

------------------------

level 5:看透本質

閱讀 Python 的 C 實現,掌握 Python 中各種對象的本質,掌握是如何通過 C 實現面向對象的行為,對於常見的數據結構,掌握其實現細節。到這一步,需要將 Python 源碼學習至少一遍,並對關鍵部分有較深層次的理解。

------------------------

level 6:手到拈來,一切皆空

不可說,不必說~

--------------------- 以下為補充說明 ---------------------------

看到評論區有朋友誤解,這裡解釋一下。

首先,以上步驟並不是打怪升級,不存在到了一級再去第下一級,你完全可以在熟練標準庫的過程中掌握語言的實現原理等,這並不矛盾。所以那些評論說「我已經 xx 級了, xx 時候要到 xx 級」的朋友們,希望不要誤解了我的意思,你不必將自己限制死,而可以很靈活的變通。

另外題干中的「招聘要求寫著「精通 Python 語言」」,對於這樣的招聘要求,絕大多數其實是 HR 腦殘(不排除少部分公司真的有特殊需求),一般面對這樣的公司我會選擇繞道而行。既然是找工作,還是要找自己滿意且公司本身很不錯的,人生苦短,何必跟自己過不去呢?說到這裡,我看知乎的招聘崗位中(知乎招聘),貌似沒有出現「精通」二字,自認技術高超的小夥伴可以去試試看喲~~~

最後,希望各位不要被某些答案「不需要精通 xx 語言」這樣的言論干擾,編程語言有很多相似的地方,個人覺得掌握一門語言的底層實現,對自身的編程水平提升是很有幫助的。但是要搞清楚,僅僅編程語言是不夠的,如何使用一門編程語言做有趣的事情,這很重要。


謝邀。但是俺回答不了啊。

我在以前找工作的時候,曾經用過「精通X」之類的詞。隨著踩得坑越多,越用越感覺自己懂的太少,要學的太多了,越用越發現它並不是自己當初一廂情願的認為的那麼簡單。

不知道每個人對「精通」的定義是什麼。對我來說,中國連一個Python核心開發者都沒有(見https://zhuanlan.zhihu.com/p/22217076),我感覺這個問題還是空白答案比較好(得罪樓上好多人啊)


  1. 當你覺得它很美的時候,你入門了。

  2. 當你覺得它很好用的時候,你掌握它了。
  3. 當你發現原來還有很多不知道的東西時,你是高手了。
  4. 當你知道這個問題沒有答案時,你已經合格了。


這個回答可能有點長,我會先給出我對精通Python的理解,然後給出一些Python中有難度的知識點。如果大家在看完我這篇回答之前,已經充分理解了我列出的各個知識點,那麼,我相信你已經算是精通Python了。如果不能,我希望這篇回答能讓你意識到自己Python知識還存在哪些不足,在之後的學習中,從哪些方面去改進。

精通是個偽命題

怎樣才算精通Python,這是一個非常有趣的問題。

很少有人會說自己精通Python,因為,這年頭敢說精通的人都會被人摁在地上摩擦。其次,我們真的不應該糾結於編程語言,而應該專註於領域知識。比如,你可以說你精通資料庫,精通分散式,精通機器學習,那都算你厲害。但是,你說你精通Python,這一點都不酷,在業界的認可度也不高。

再者,Python使用範圍如此廣泛,一個人精力有限,不可能精通所有的領域。就拿Python官網的Python應用領域來說,Python有以下幾個方面的應用:

  • Web Programming: Django, Pyramid, Bottle, Tornado, Flask, web2py

  • GUI Development: wxPython, tkInter, PyGtk, PyGObject, PyQt

  • Scientific and Numeric: SciPy, Pandas, IPython

  • Software Development: Buildbot, Trac, Roundup

  • System Administration: Ansible, Salt, OpenStack

如果有人聲稱精通上面所有領域,那麼,請收下我的膝蓋,並且,請收我為徒。

既然精通Python是不可能也是沒有意義的事情,那麼,為什麼各個招聘要求裡面,都要求精通Python呢?我覺得這都是被逼的。為什麼這麼說呢,且聽我慢慢說來。

為什麼招聘要求精通Python

絕大部分人對Python的認識都有偏差,認為Python比較簡單。相對於C、C++和Java來說,Python是比較容易學習一些,所以,才會有這麼多只是簡單地了解了一點語法,就聲稱自己會Python的工程師。

打個比方,如果一個工程師,要去面試一個C++的崗位,他至少會找一本C++的書認真學習,然後再去應聘。Python則不然,很多同學只花了一點點時間,了解了一下Python的語法,就說自己熟悉Python。這也導致Python的面試官相對於其他方向的面試官,更加容易遇到不合格的求職者,浪費了大家的時間。Python面試官為了不給自己找麻煩,只能提高要求,要求求職者精通Python。

怎樣才算精通Python

既然精通Python本身是一件不可能的事情,而面試官又要求精通Python,作為求職者,應該達到怎樣的水平,才敢去應聘呢?我的觀點是,要求精通Python的崗位都是全職的Python開發,Python是他們的主要使用語言,要想和他們成為同事,你至少需要:

1. 能夠寫出Pythonic的代碼(什麼是Pythonic的代碼,請看我在另一個問題下的回答:怎樣才能寫出pythonic的代碼? - 知乎用戶的回答)

2. 對Python的一些高級特性比較熟悉

3. 對Python的優缺點比較了解

這樣說可能比較抽象,不太好理解。我們來看幾個例子,如果能夠充分理解這裡的每一個例子,那麼,你完全能夠順利通過"精通Python"的崗位面試。

敢來挑戰嗎

1.上下文管理器

大家在編程的時候,經常會遇到這樣的場景:先執行一些準備操作,然後執行自己的業務邏輯,等業務邏輯完成以後,再執行一些清理操作。

比如,打開文件,處理文件內容,最後關閉文件。又如,當多線程程序需要訪問臨界資源的時候,線程首先需要獲取互斥鎖,當執行完成並準備退出臨界區的時候,需要釋放互斥鎖。對於這些情況,Python中提供了上下文管理器(Context Manager)的概念,可以通過上下文管理器來控制代碼塊執行前的準備動作以及執行後的收尾動作。

我們以處理文件為例來看一下在其他語言中,是如何處理這種情況的。 Java風格/C++風格的Python代碼:

myfile= open(r"C:miscdata.txt")
try:
for line in myfile:
...use line here...
finally:
myfile.close()

Pythonic的代碼:

with open(r"C:miscdata.txt") as myfile:
for line in myfile:
...use line here...

我們這個問題討論的是精通Python,顯然,僅僅是知道上下文管理器是不夠的,你還需要知道:

1. 上下文管理器的其他使用場景(如資料庫cursor,鎖)

    • 上下文管理器管理鎖

class FetchUrls(threading.Thread):
...
def run(self):
...
with self.lock: #使用"with"語句管理鎖的獲取和釋放
print "lock acquired by %s" % self.name
print "lock released by %s" % self.name

    • 上下文管理器管理資料庫cursor

import pymysql

def get_conn(**kwargs):
return pymysql.connect(host=kwargs.get("host", "localhost"),
port=kwargs.get("port", 3306),
user=kwargs.get("user"),
passwd=kwargs.get("passwd"))

def main():
conn = get_conn(user="laimingxing", passwd="laimingxing")
with conn as cur:
cur.execute("show databases")
print cur.fetchall()

if __name__ == "__main__":
main()

    • 上下文管理器控制運算精度

with decimal.localcontext() as ctx:
ctx.prec = 22
print(decimal.getcontext().prec)

2. 上下文管理器可以同時管理多個資源

假設你需要讀取一個文件的內容,經過處理以後,寫入到另外一個文件中。你能寫出Pythonic的代碼,所以你使用了上下文管理器,滿意地寫出了下面這樣的代碼:

with open("data.txt") as source:
with open("target.txt", "w") as target:
target.write(source.read())

你已經做得很好了,但是,你時刻要記住,你是精通Python的人啊!精通Python的人應該知道,上面這段代碼還可以這麼寫:

with open("data.txt") as source, open("target.txt", "w") as target:
target.write(source.read())

3. 在自己的代碼中,實現上下文管理協議

你知道上下文管理器的語法簡潔優美,寫出來的代碼不但短小,而且可讀性強。所以,作為精通Python的人,你應該能夠輕易地實現上下文管理協議。在Python中,我們就是要自己實現下面兩個協議:

    • __enter__(self) Defines what the context manager should do at the beginning of the block created by the with statement. Note that the return value of __enter__ is bound to the target of the with statement, or the name after the as.
    • __exit__(self, exception_type, exception_value, traceback) Defines what the context manager should do after its block has been executed (or terminates). It can be used to handle exceptions, perform cleanup, or do something always done immediately after the action in the block. If the block executes successfully, exception_type, exception_value, and traceback will be None. Otherwise, you can choose to handle the exception or let the user handle it; if you want to handle it, make sure __exit__ returns True after all is said and done. If you don"t want the exception to be handled by the context manager, just let it happen.

2. 裝飾器

由於我們這個問題的題目是精通Python,所以,我假設大家已經知道裝飾器是什麼,並且能夠寫簡單的裝飾器。那麼,你是否知道,寫裝飾器也有一些注意事項呢。

我們來看一個例子:

def is_admin(f):
def wrapper(*args, **kwargs):
if kwargs.get("username") != "admin":
raise Exception("This user is not allowed to get food")
return f(*args, **kwargs)
return wrapper

@is_admin
def barfoo(username="someone"):
"""Do crazy stuff"""
pass

print barfoo.func_doc
print barfoo.__name__

None
wrapper

我們用裝飾器裝飾完函數以後,無法正確地獲取到原函數的函數名稱和幫助信息,為了獲取這些信息,我們需要使用@functool.wraps。 如下所示:

import functools

def is_admin(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
if kwargs.get("username") != "admin":
raise Exception("This user is not allowed to get food")
return f(*arg, **kwargs)
return wrapper

再比如,我們要獲取被裝飾的函數的參數,以進行判斷,如下所示:

import functools
def check_is_admin(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
if kwargs.get("username") != "admin":
raise Exception("This user is not allowed to get food")
return f(*args, **kwargs)
return wrapper

@check_is_admin
def get_food(username, food="chocolate"):
return "{0} get food: {1}".format(username, food)

print get_food("admin")

這段代碼看起來沒有任何問題,但是,執行將會出錯,因為,username是一個位置參數,而不是一個關鍵字參數,我們在裝飾器裡面,通過kwargs.get("username")是獲取不到username這個變數的。為了保證靈活性,我們可以通過inspect來修改裝飾器的代碼,如下所示:

import inspect
def check_is_admin(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
func_args = inspect.getcallargs(f, *args, **kwargs)
print func_args
if func_args.get("username") != "admin":
raise Exception("This user is not allowed to get food")
return f(*args, **kwargs)
return wrapper

裝飾器還有很多知識,比如裝飾器怎麼裝飾一個類,裝飾器的使用場景,裝飾器有哪些缺點,這些,你們都知道嗎?感興趣的同學 可以看我以前的一篇博客(python裝飾器入門與提高)

3. 全局變數

關於Python的全局變數,我們先從一個問題開始:Python有沒有全局變數?可能你看到這個問題的時候就蒙圈了,沒關係,我來解釋一下。

從Python自己的角度來說,Python是有全局變數的,所以,Python為我們提供了global關鍵字,我們能夠在函數裡面修改全局變數。但是,從C/C++/Java程序員的角度來說,Python是沒有全局變數的。因為,Python的全局變數並不是程序級別的(即全局唯一),而是模塊級別的。模塊就是一個Python文件,是一個獨立的、頂層的命名空間。模塊內定義的變數,都屬於該命名空間下,Python並沒有真正的全局變數,變數必然屬於某一個模塊。

我們來看一個例子,就能夠充分理解上面的概念。三種不同的修改全局變數的方法:

import sys

import test

a = 1

def func1():
global a
a += 1

def func2():
test.a += 1

def func3():
module = sys.modules["test"]
module.a += 1

func1()
func2()
func3()

這段代碼雖然看起來都是在對全局變數操作,其實,還涉及到命名空間和模塊的工作原理,如果不能很清楚的知道發生了什麼,可能需要補充一下自己的知識了。

4. 時間複雜度

我們都知道,在Python裡面list是異構元素的集合,並且能夠動態增長或收縮,可以通過索引和切片訪問。那麼,又有多少人知道,list是一個數組而不是一個鏈表

關於數組和鏈表的知識,我想大家都知道了,這裡就不再贅述。如果我們在寫代碼的過程中,對於自己最常用的數據結構,連它的時間複雜度都不知道,我們又怎麼能夠寫出高效的代碼呢。寫不出高效的代碼,那我們又怎麼能夠聲稱自己精通這門編程語言呢。

既然list是一個數組,那麼,我們要使用鏈表的時候,應該使用什麼數據結構呢?在寫Python代碼的時候,如果你需要一個鏈表,你應該使用標準庫collections中的deque, deque是雙向鏈表。標準庫裡面有一個queue,看起來和deque有點像,它們是什麼關係?這個問題留著讀者自己回答。

我們再來看一個很實際的例子:有兩個目錄,每個目錄都有大量文件,求兩個目錄中都有的文件,此時,用Set比List快很多。因為,Set的底層實現是一個hash表,判斷一個元素是否存在於某個集合中,List的時間複雜度為O(n),Set的時間複雜度為O(1),所以這裡應該使用Set。我們應該非常清楚Python中各個常用數據結構的時間複雜度,並在實際寫代碼的過程中,充分利用不同數據結構的優勢。

5. Python中的else

最後我們來看一個對Python語言優缺點理解的例子,即Python中增加的兩個else。相對於C++語言或者Java語言,Python語法中多了兩個else。

一個在while循環或for循環中:

while True:
....
else:
....

另一個在try...except語句中:

try:
....
except:
....
else:
....
finally:
....

那麼,哪一個是好的設計,哪一個是不好的設計呢?要回答這個問題,我們先來看一下在大家固有的觀念中,else語句起到什麼作用。在所有語言中,else都是和if語句一起出現的:

if &
statement1
else
statement2

翻譯成自然語言就是,如果條件滿足,則執行語句1,否則,執行語句2。注意我們前面的用語,是否則,也就是說,else語句在我們固有的觀念中,起到的作用是「否則」,是不滿足條件的情況下才執行的。

我們來看Python中,while循環後面的else語句。這個else語句是在while語句正常結束的時候執行的。所以,按照語意來說,while循環的else起到的作用是and。也就是說,在Python中,while循環末尾的else換做and才是更加合適的。

你可能覺得我有點鑽牛角尖,那好,我再強調一遍,while循環中的else語句是在循環正常結束的時候執行的,那麼請問:

1. 如果while循環裡面遇到了break語句,else語句會執行嗎

2. 如果while循環最後,遇到了continue語句,else語句還會執行嗎

3. 如果while循環內部出現異常,else語句還會執行嗎

這裡的幾個問題,大多數人都不能夠很快的正確回答出來。而我們的代碼是寫給人看的,不應該將大多數人排除在能夠讀懂這段代碼之外。所以我認為,Python語言中循環語句末尾的else語句是一個糟糕的設計

現在,我們再來看try...except語句中的else,這個else設計得特別好,其他語言也應該吸取這個設計。這個設計的語義是,執行try裡面的語句,這裡面的語句可能會出現異常,如果出現了異常,就執行except裡面的語句,如果沒有出現異常,就執行else裡面的語句,最後,無論是否出現異常,都要執行finally語句。這個設計好就好在,else的語句完全和我們的直觀感受是一樣的,是在沒有出現異常的情況下執行。並且,有else比沒有else好,有了else以後,正確地將程序員認為可能出現異常的代碼和不可能出現異常的代碼分開,這樣,更加清楚的表明了是哪一條語句可能會出現異常,更多的暴露了程序員的意圖,使得代碼維護和修改更加容易。

結論:我這篇回答很長,但是,我相信對很多人都會有幫助。這裡想說的是,Python是一門編程語言,使用範圍非常廣泛,大家不要去追求精通Python程序語言自身,而應該將精力放在自己需要解決的實際問題上。其次,絕大多數人對Python的認識都存在誤區,認為Python很簡單,只是簡單地了解一下就開始寫Python代碼,寫出了一堆很不好維護的代碼,我希望這一部分人看到我的回答以後,能夠回去重新學習Python。最後,對於一些同學的疑慮——招聘職位要求精通Python,我的回答是,他們並不奢望招到一個精通Python的人,他們只是想招到一個合格的工程師,而大部分的Python工程師,都,不,合,格!

如果你喜歡我這篇回答(那就點贊以示鼓勵),可能對我這篇回答也會感興趣:

怎樣才能寫出pythonic的代碼? - 知乎用戶的回答

Python 有哪些優雅的代碼實現?讓自己的代碼更pythonic - 知乎用戶的回答


更新:

之前在組裡分享過,後端那些事,有興趣可以看看。

要想精通python,寫的代碼首先得pythonic,自己閉門造車肯定不行,肯定需要研讀牛B的開源代碼,在這過程中會遇到python的許多高階用法

1.裝飾器 裝飾器在框架中運用的很多,比如flask_login,要精通至少很隨意的寫出滿足需求的裝飾器,用裝飾器肯定需要functools模塊的支持

2.生成器 說道生成器就自然地聯繫到各種推導式(列表,元祖,欄位,集合),那肯定也要提到itertools模塊,contextlib標準庫中是個典範,說到contextlib就需要提到with協議,迭代器協議,以及標準庫中的哪些實現了它們,如文件描述符,線程鎖,繼續延伸的話需要了解greenlet提供的協程,那就不得不提gevent,eventlet

3.描述符 這你就得知道所有的函數其實都是描述符,property,classmethod,staticmethod都是通過描述符實現的,那就得提到werkzeug和bottle都提供的cached_property,都是訪問屬性的就得提到

__getattr__和__getattribute__,知道在合適的時候定義合適的方法簡化流程

4.元類 其實這玩意用處很大,如sqlalchemy,django的orm中field的定義都用到了它,那你得知道當python解析py時,發現__metaclass__的時候就會調用元類的__new__和__init__,如果你理解元類的__new__和__init__的第一個參數都是類(而不是self)那元類就差不多了

5.多線程 雖說python由於gil的限制不能利用多核,但在處理io密集型的任務還是有很大好處的,

那得知道threading.RLock是線程可重入鎖,daemon thread的用處(python執行環境會等待所有非daemon thread的結束),Queue是線程安全的鎖,logging是線程安全的日誌模塊,還有線程池也要熟悉

6.其它 如python2,6/7包含了不少新特性,如abc模塊的抽象方法機制,collections提供的有用容器,python中的編碼問題,super為啥需要兩個參數,而3不需要參數,經典的閉包問題,NotImplemented和NotImplementedError的區別,多繼承的mro問題,相對導入原理(__name__,如果看最新開源代碼,基本都是相對導入)......

其實還有很多,但更多的是和業務相關,比如正則表達式,那至少得知道貪婪,非貪婪,命名組等。搞伺服器開發,socket,twisted,gevent肯定要精通。搞web開發,django,flask,tornado得熟悉。。。。


我只是用python來做我的實驗,實現我的演算法,我遇到什麼問題就是簡單的看看手冊裡面怎麼使用python,沒有過多的糾結如何去精通它。python給我帶來的好處就是:它在實現演算法時候更快速更高效,本來用c++需要寫幾天的東西,python很快就寫完了,實驗可以更快的得到結果。應該說:語言是為人服務的,而你的使用目的也決定了這門語言到底帶給你什麼。


的確,在招聘要求上寫「精通XX技術」的都可以理解為是句廢話。程序員大部分都是較真的人,看到精通xx的要求很多人就想自己肯定不算精通,雖然也有10w+以上的代碼量了。奉勸招聘單位,少寫這樣的要求,否則很多合格的人可能因為自謙而不敢面試,翻完「30天精通XX」的人可能都跑來面試了。

再廢話一下學語言的態度。其實寫代碼跟寫文章沒什麼兩樣,就拿寫文章來說,你寫的是嚴謹科學的論文呢,還是文字爐火純青又優雅的散文呢?你寫的是宏篇巨著,比如「戰爭與和平」之類,還是寫一個通知呢?如果寫的是論文,可以類比普通的軟體,簡單、直觀、好維護、結構清晰就OK了,如果寫的是散文,類比那些NB人物寫的精巧框架,使用了很多語言技巧,展現了NB人物對該語言的深刻理解,適用於流芳百世類型。如果寫宏篇巨著,比如一個大型的業務系統、操作系統等,就涉及到架構問題了,語言的重要性退居2位,寫個通知,隨便吧,能用就行。


我認為「精通」要滿足如下條件:

  1. 熟知主流硬體體系(x86, x64)
  2. 熟知 CPython 的具體實現,如若可能至少通讀源碼三遍以上

  3. 熟知每條 Python bytecode 如何被解釋執行

  4. 熟知每條 Python 語句如何 compile 成 bytecode

  5. 熟知 Python 主要數據結構所採用的優化手段
  6. 熟知 JIT 以及哪些場合下 PyPy 會比 CPython 有較大性能提高、以及有什麼代價

所以我一直只敢稱自己為 「中級 Pythonista」。對於那些僅僅知道怎麼用 Python 就敢自稱「精通」的人:專家不是那麼好當的,沒有金剛鑽別攬瓷器活。不懂那麼多底層細節就不要隨便說自己「精通」,說自己「擅長」不會被人看不起。

@米嘉 引用的 StackOverflow 上列的那幾項條件是作為將 Python 用於主要工作語言所需要的基本條件,敢於因此而稱自己「精通 Python」要讓不少人笑掉大牙。況且那幾項還有幾個嚴重問題:

  • 第3點:如若可能,盡量避免 map/reduce/fitler,而用 list/generator/set comprehension,代碼要清晰得多,GvR 如此說。xrange 和 range 的區別在 Python 3 中馬上就要滾蛋了,所以如非必要,不要大量使用 xrange。
  • 第5點:敢於在 CPython 中大量使用遞歸是對 CPython 實現的公然侮辱。Python 的多個穩定實現都沒有 TCO,遞歸會讓性能迅速下降。記住一點:Python 中函數調用非常昂貴,可讀性、可維護性影響不大的情況下,能展開函數調用的時候盡量展開、遞歸能轉化成循環的盡量轉化。遞歸也不是人類自然的思考方式。
  • 第7點:看書是對的,但不要把 Python 當作一門經典函數式語言對待,因為它不是。你當它是,它會很痛苦(「為毛要這樣濫用我!?」),你也會很痛苦(「為毛你不這樣實現 blah blah!?」)。SICP 是本好書,但不要因此而教條。要清楚的知道什麼時候用函數式,什麼時候用面向對象,什麼時候用面向過程,什麼時候用面向任務,什麼時候用面向結果。在一棵樹上弔死是大多數非理性死忠的表現。


我覺得根本就不存在所謂的精通python,C,java或任何一種編程語言。

只能是精通:tcp ip,http,數學建模,最優化,設計模式,數據挖掘,概率論,圖像處理,資訊理論和編碼,信息安全和加密,操作系統,編譯原理,arm架構,等等等等。

語言終歸只是工具,所謂精通語言對於多數人一點用都沒有,除非你要自己設計一門語言。就好比於我精通漢語,知道各種生僻字,知道一個字的六種寫法,這並沒多大用處。重要的能構思奇妙故事的想像力,能準確解讀文字的閱歷和思維能力。

對於編程來說,語言就是不斷製造的工具,比精通工具更重要的是:如何用工具解決問題,明白工具是如何解決問題的。

另外針對一些知友在評論中提的意見,我補充一下自己的看法:

我沒有說不要語言,只是說重點不是語言。我反對的是一些片面追求語言表達技法的風氣。程序的本質是程序的內容,而不是程序的表達形式。你寫一篇文章,重要的文章寫了什麼,是不是言之有物,你的文章是漢語寫的還是英語寫的並不重要,「茴」字有幾種寫法也不重要。當然了,語言本身太弱是做不出產品的。找文盲來寫文章當然寫不出來,這樣的情況,就不要討論了吧。

另外我很贊同@brambles 的看法,我認為討論編程不應該按照語言來劃分,應該按照具體技術來劃分

比如說

討論科學計算,都是矩陣計算,各種演算法,用python還是matlab實現都差不多;

討論圖形界面程序,都是各種控制項,導航,用qml和xaml又有多大區別呢;

討論操作系統,重點是上下文切換,堆棧指針,中斷,系統調用,資源管理等,用c還是用c++都是要做同樣的東西。

相反

python的科學計算和python的爬蟲 之間的差異,比python的科學計算和matlab大的多;

linux 內核和gtk的差異,遠大於gtk和qt的差異;


我個人是很反對對一個語言使用「精通」這個詞的。因為廣大碼農嘴裡的「精通xxx」實際上毫無意義。代表不了任何東西。

代碼是一個工具,就像一隻筆一樣。你精通「使用」這隻筆是毫無卵用的,而廣大碼農嘴裡「精通xxx語言」其實就是精通」使用「xxx語言而已。

精通使用一隻筆是沒有太大意義的(但是前提必須要基本會用哈),有意義的是你精通拿這隻筆來做什麼事,是拿來寫書法、寫文章或者是畫畫。然而寫書法好的人換一隻不那麼熟的筆就不會寫字了嗎?寫文章的換隻筆就寫不出好文章了?畫畫的換隻筆就畫不出畫了?

那這書法,文章、畫畫代表的是什麼呢?領域!

你們要明白:

搞安卓的Java和搞J2E的Java不是一個Java

搞嵌入式的c和搞桌面應用的c不是一個c

搞遊戲引擎的c++和搞jvm的c++也不是一個c++

搞科學計算的python和搞web的python也不是一個python


先說好,我的回答僅限於這個問題。

讓我們拿游泳來打比方吧。

某個游泳池要開業,所以需要一些救生員。於是他就貼出了求職公告。誠聘救生員,需精通游泳,待遇從優,非誠勿擾。

然後有人就在X乎上問了。大神們,什麼叫做精通游泳?

嘛,我覺得吧,你起碼得能在平靜水面游個200米吧。

哎呀這個太基本了。既然是精通游泳,起碼你得把蛙泳仰泳蝶泳自由泳各來個一公里吧。

年輕人,不要總想著搞個大新聞。主席暢遊長江,談笑風生,也沒敢自稱精通游泳。你游沒游過長江啊。

半年後,游泳池倒閉了。

HR寫「精通」的意思是,請新手有自知之明,我們需要一些能解決我們問題的人。什麼叫能解決問題其實他也不明白,反正Team Leader滿意就行。他希望的是差不多就得了,多來幾個人才是正事(這才是人家的KPI)。而不是一年總共才上門一個人,而且還是個龜叔這個級別的人。實際上龜叔真的來了他才不知道該怎麼辦才好。就好像泳池招聘廣告,只是希望你能在需要的時候,跳下去救人。而不是希望在泳池的旁邊,養四個菲爾普斯。。。


不要局限於教條。所謂精通,就是能夠用Python解決你的大多數問題,而且感覺還比較滿意即可。不用考慮別人怎麼看精通(除非你要給HR、獵頭看)。


讀完《Python源碼剖析》,並進一步將全部最新源代碼邏輯整理完畢。


大家目的都不一樣好么,一種屬於極客類,要從源碼搞起,非得整得每個細節都不放過,一種是實用主義,OK?,我知道什麼時候該用,什麼時候怎麼用,畢竟,語言是門工具,對有些數據,java,R更適合數據的挖掘,為什麼還要捧著聖杯,不肯下來呢?任何一門語言,都是為了服務人解決各類問題的產生的,存在即合理,沒有優劣之分,所謂精通,只不過是旁人對你的評價罷了,認為你用的6而已。而對自己而言,我認為了解到什麼程度就OK,難道我搞高光譜圖像分類,我還需要知道高光譜儀什麼原理么?我用微積分,我還需要證明1+1=2?

~~~~~~~~~~~~~~~~~~~~~~~~

個人理解,請允許有不同的聲音。


不需要精通就能用的很開心的語言


我覺得,我們學語言的目的應該是用語言來解決我們遇到的問題,來實現我們的想法,而不是把語言修鍊到什麼境界。語言說到底只是工具而已。


有幸上過Raymond Hettinger的課

引用下Raymond的大概標準

1.了解主要數據結構, 底層實現,和常用相關優化法.

2.了解class和object在python里怎麼實現的(相關metaclass的知識)

3. 熟悉相關庫

4. 了解cpython和pypy

5. 一顆謙虛, 謹慎而且好學的心


話說

人生苦短 我用 Python

人家就是希望不必搞什麼精通才弄了這個語言出來的

不過如果你真的要死磕...

等你知道我翻譯這篇

The Zen of Python

錯了哪些

錯在哪裏

你算是大致知道 Python 是個什麼樣的語言了

至於精通...

(我心目中最恐怖精通 Python 的男人用 m4 寫了一個小 python 來玩這件事我會隨便說嗎???)

(m4 是什麼語言自己去 google...)

我不改是因爲我實在找不出更漂亮的韻文來翻譯了...

就這樣吧The Zen of Python

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren"t special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you"re Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it"s a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let"s do more of those!


當你看python不是世界上最好的語言而是能看出有各種問題或者局限的時候……

沒有具體的指標,看每個人具體用的東西……generator啊裝飾器啊那些我覺得真不算高深的東西……即使是更高級的主題,也可能有的人永遠涉及不到GIL,有些人可能永遠用不到metaclass,有的人ctype都不需要,所以根本沒有高票那種所謂標準的東西……

ps 還有就是去看各個版本python

的changelog的時候,大概能知道為什麼新版本要做這些update的時候……


引用自StackOverflow上的一個答案:

  1. 掌握 list comprehensions
  2. 掌握 generators
  3. 代碼中經常使用 map, reduce, filter, iter, range, xrange

  4. 掌握 Decorators
  5. 大量使用遞歸函數
  6. 掌握 itertools 和 functools
  7. 讀書 —— Real World Haskell(評論中作者說不一定要局限於這本書,可以閱讀任何關於函數式編程的書籍,比如SICP等)

  8. 重寫自己的老派Python代碼,使用高階函數,遞歸等
  9. 當你同事給你看任何用Python做的類實現時,煩死他。告訴他更好的辦法時通過dictionary加上函數,擁抱函數編程。
  10. 重新掌握 Strategy 及其他模式
  11. 找到平衡

StackOverflow上的問題:Python progression path - From apprentice to guru (http://stackoverflow.com/questions/2573135/python-progression-path-from-apprentice-to-guru)


推薦閱讀:

三峽發電量估算系統在葛洲壩中的應用可行性分析
python與numpy使用的一些小tips(1)
小說人物關係的可視化
限時加入!國內第二個千人Python自動化運維實名社群成立
Python 結巴分詞(jieba)源碼分析

TAG:程序員 | Python | 編程 |