有羣友問過,是什麼緣由使我開始寫技術公衆號,又是什麼動力讓我堅持寫的。java
在我看來,寫做是一件不能敷衍的事,經過寫做來學習,反而要比單純地學習的效果要好。爲了寫成一篇「拿得出手」的文章,我要反覆查找資料,閱讀與思考,拆解與整合,最終寫成的時候,也是知識的拼圖成型的時候。python
因此,對我來講,寫做是一種咀嚼信息然後提煉知識,最終拓展成技能與認知的過程。雖然這個過程很緩慢,但曾經的急進方式並無速成的效果啊,不妨就這樣一文章一腳印地試試看咯。函數
除此以外,還有一個很重要的緣由。文章是一種公共對話的媒介,它是一個展現的窗口,也是一個接收反饋的通道。經過寫做,我有了跟其它學習者對話的機會。學習
看書學習可能只是我的的事情,可是,在寫做平臺上發佈文章,這就超越了我的行爲——你得隨時準備着被批評、或者被請教、或者被誤解、甚至是被無視(這是最多見的結果)。ui
我享受寫做文章,來跟其餘處在相同處境的同窗們交流,來向更優秀的大牛們學習取經。spa
這就是我目前寫技術文章的一些我的體會吧。翻譯
對於上面提到的第二個緣由,我最近很有感觸,想要多聊一些。爲了更有針對性,本文姑且限定一個話題吧,那就是「寫做技術文章,如何看待他人的批評/意見」。代碼規範
有些聲音其實只是主觀見解,我認爲能夠和而不一樣。code
主觀世界每每沒有確切的對錯之分,畢竟——思想無罪 。對象
面對主觀性的意見,我認爲要作到有理有據,堅持一點個性,最後會獲得別人的尊重。
好比,在翻譯 Python 社區的七種治理模式的時候,有一個提案是「Python Governance Model Lead by Trio of Pythonistas」,我將它翻譯成「三巨頭治理模式」。有同窗就指出,「Trio」應該翻譯成「三人組」或者「三重奏」,翻譯成「三巨頭」是什麼意思?
這種留言,我認爲是主觀性的意見,應求同存異。
我之因此這麼翻譯,一方面考慮,它要替代的是「終身仁慈獨裁者」,三巨頭對獨裁者,意味深長;另外一方面,我腦子裏總想着一個皇帝死了,而後政權被三個攝政大臣把持,這種政治畫面揮之不去,雖然是不着邊際,但挺有趣味,因此我不願放棄這「三巨頭」的譯法。
主觀性的意見帶入了提出者的我的知識背景、思想結構、以及話語習慣等等,我以爲要先嚐試交流,相互交換,能融洽兼容則最好啦,不能的話,及時終止。
客觀性的意見有以下幾種:筆誤(錯別字和其它疏忽)、代碼規範、知識性錯誤……
對於筆誤性的錯誤,這沒啥好說的,我本身發現過幾處,也被讀者指出過幾處。有則改之就好。
對於代碼規範,有時候爲了舉例方便,確實沒有按照規範來。儘可能避免,求一個兼顧。
知識性錯誤是要熱烈歡迎的——不是說歡迎錯誤,而是說歡迎別人來指出我所未知的錯誤。
出現知識性的錯誤,就意味着沒有全面掌握知識,一旦出現,就必然意味着有提高的空間。原本覺得知道了什麼,若是被指出了錯誤,那改正後,纔是真的知道了什麼。
知道本身不知道而且改正之,並不可恥,不知道本身不知道,這纔可憐。
在寫《Python是否支持複製字符串呢?》的時候,我根據已得的知識,以及查閱到的資料,早早就得出了一個很滿意的結論。最後成文前,臨時地加了一個未做驗證的示例,沒想到這會是一個致命的反例,推翻了前面辛辛苦苦創建起來的一切。
這是一個客觀性的錯誤,一被指出的時候,很快就能驗證。由於這個錯誤,我從新梳理了相關的知識點,組成新的知識面,寫成了一篇《join()方法的神奇用處與Intern機制的軟肋》。
還有一個例子,前不久的《Python進階:自定義對象實現切片功能》,我在準備素材的時候,竟採用了一個不嚴謹的例子,並且自做聰明地批判了別人的實際無誤的例子。最後,有讀者留言了很長的不一樣觀點,我才意識到本身的錯誤!
得益於讀者的留言,我修正了本身的錯誤,並且在修正過程當中,也增強了對於其它知識的理解,真是因禍得福焉知非福啊。
這裏還有一個客觀性錯誤,藏得特別深,可能真的有 90% 的 Python 使用者不知道。
特別感謝 @xpresslink 同窗指出。下面,我給你們分享一下。
在文章《爲何range不是迭代器?range究竟是什麼類型?》裏,個人注意點其實就在標題的兩個問句裏,大部分的留言互動也是基於此。但最後,很意外地,一名讀者指出了一個客觀性錯誤,讓我有了額外的收穫。
這位同窗指出我有些基本的概念是錯誤的:
「range() 函數」這個說法是很是明顯有錯誤的,range 不是內置函數( builtin method )而是個類對象,在 python 裏面不要見到用括號調用的東西就認爲是函數,相似的仍是有不少,如 list, set, tuple, dict 等,這些都是類, 特別是 enumerate ,這個學 python 的人十有八九認爲是函數而不知道是類,加了括號是實例化而不是函數調用。
python 中類的實例化和函數調用很是容易對新手有大的迷惑性,相對來講在 java 中有明確的 new 關鍵字加在構造方法前面概念更清楚一些。
根據這個評論,我就去查看文檔。
上圖中 range() 雖然被歸類到 Built-in Functions 裏面,可是官方描述的是「functions and types」,便是說,在內置函數的大類下面,包含了內置函數與內置類。
那 range() 屬於哪種呢?看看它的解釋:
Rather than being a function, range is actually an immutable sequence type……
range 實際是一種不可變的序列類型,而非一個(內置)函數……
按照這裏的說法,官方已經區分了 range() 不是函數,正像那位留言的同窗所說。
我第一反應固然是不能接受。我怎麼會認爲它是內置函數的呢,難道不是根據學習資料得來的麼?難道我學習的資料是錯的?爲什麼歷來沒看到有人對此作過辨析呢?
根據羣友的提示,我去查看 Python2 的文檔,而後就發現了頗有意思的地方:
首先一點, Built-in Functions 的描述跟 Python3 有點不一樣,它寫的是 「functions」,並不包含「types」;還有一點,在 range() 和 xrange() 的具體內容中,官方都是稱呼它們爲 function 。
由此看來,Python2 的官方文檔就把 range() 當成內置函數,這個認識錯誤是有根源的!等到 Python3 的時候,官方把錯誤改正過來了,然而改得並不完全。纔有了前面同時存在「functions and types」的描述。
官方已經把 range() 與 xrange() 規範爲一個,或許在從此版本,還會專門分出一類 Built-in Types 來存放像 range() 和 enumerate() 這些內置類吧。
在那以前,我只能先行給你們提個醒了:別再誤覺得 range() 是內置函數了。
那麼,怎麼辨別哪些是內置函數呢?
我想到了兩個方法:
(1)看是否存在對應的魔術方法。例如,len() 是一個內置函數,由於它實際調用的是魔術方法__len__()
;還有最近一直在提的 iter(),它調用的是__iter__()
,因此也是內置函數;而由於不存在 __range__()
魔術方法,因此 range() 不是內置函數。
(2)使用 type() 進行判斷,結果爲 builtin_function_or_method
的纔是內置函數。
>>> type(len) builtin_function_or_method >>> type(sorted) builtin_function_or_method >>> type(open) builtin_function_or_method >>> type(range) type >>> type(enumerate) type >>> type(str) type
像 open 和 sorted 並無對應的魔術方法,但判斷出來都是內置函數;而 str 雖有對應魔術方法,但判斷是 type ,這意味着,以上兩種方法得要結合起來看。
我不肯定有多少人事先知道怎麼區份內置函數與內置類,但我確實沒看到過對這個問題進行辨析的文章,因此,此次是真正漲知識了,也但願這篇文章,可以消除一些讀者的錯誤觀念吧。
我最近寫的一些文章都不是心血來潮,無論是字符串系列、切片系列仍是迭代器系列,本意都是想在一個主題上進行深刻的多面性的思考與記錄。
若是沒有一些熱心讀者的指正,我恐怕是很難知道本身錯在了哪裏,若是不是有這麼多的認同以及意見,我恐怕也缺少動力堅持寫下去。
最後鳴謝幾位提意見的小能手同窗(時間順序,可能有漏):@瘋琴、@德瑪西亞之翼奎因、@發條橙、@gaieepo、@郭芮、@aijam、@xpresslink、@進擊的糰子、@不換……
相關連接(單有錯,雙修正):
-----------------
本文原創並首發於公~衆~號【Python貓】,後臺回覆「愛學習」,免費得到20+本精選電子書。