聊聊技術寫作的個人體會

来源:https://www.cnblogs.com/pythonista/archive/2019/01/11/10252945.html
-Advertisement-
Play Games

有群友問過,是什麼原因使我開始寫技術公眾號,又是什麼動力讓我堅持寫的。 在我看來,寫作是一件不能敷衍的事,通過寫作來學習,反而要比單純地學習的效果要好。為了寫成一篇“拿得出手”的文章,我要反覆查找資料,閱讀與思考,拆解與整合,最終寫成的時候,也是知識的拼圖成型的時候。 所以,對我來說,寫作是一種咀嚼 ...


 

有群友問過,是什麼原因使我開始寫技術公眾號,又是什麼動力讓我堅持寫的。

在我看來,寫作是一件不能敷衍的事,通過寫作來學習,反而要比單純地學習的效果要好。為了寫成一篇“拿得出手”的文章,我要反覆查找資料,閱讀與思考,拆解與整合,最終寫成的時候,也是知識的拼圖成型的時候。

所以,對我來說,寫作是一種咀嚼信息而後提煉知識,最終拓展成技能與認知的過程。雖然這個過程很緩慢,但曾經的急進方式並沒有速成的效果啊,不妨就這樣一文章一腳印地試試看咯。

除此之外,還有一個很重要的原因。文章是一種公共對話的媒介,它是一個展示的視窗,也是一個接收反饋的通道。通過寫作,我有了跟其它學習者對話的機會。

看書學習可能只是個人的事情,但是,在寫作平臺上發佈文章,這就超越了個人行為——你得隨時準備著被批評、或者被請教、或者被誤解、甚至是被無視(這是最常見的結果)。

我享受寫作文章,來跟其他處在相同處境的同學們交流,來向更優秀的大牛們學習取經。

這就是我目前寫技術文章的一些個人體會吧。

對於上面提到的第二個原因,我最近頗有感觸,想要多聊一些。為了更有針對性,本文姑且限定一個話題吧,那就是“寫作技術文章,如何看待他人的批評/意見”。

1、主觀性的意見

有些聲音其實只是主觀看法,我認為可以和而不同。

主觀世界往往沒有確切的對錯之分,畢竟——思想無罪

面對主觀性的意見,我認為要做到有理有據,堅持一點個性,最後會得到別人的尊重。

比如,在翻譯 Python 社區的七種治理模式的時候,有一個提案是“Python Governance Model Lead by Trio of Pythonistas”,我將它翻譯成“三巨頭治理模式”。有同學就指出,“Trio”應該翻譯成“三人組”或者“三重奏”,翻譯成“三巨頭”是什麼意思?

這種留言,我認為是主觀性的意見,應求同存異。

我之所以這麼翻譯,一方面考慮,它要替代的是“終身仁慈獨裁者”,三巨頭對獨裁者,意味深長;另一方面,我腦子裡總想著一個皇帝死了,然後政權被三個攝政大臣把持,這種政治畫面揮之不去,雖然是不著邊際,但挺有趣味,所以我不肯放棄這“三巨頭”的譯法。

主觀性的意見帶入了提出者的個人知識背景、思想結構、以及話語習慣等等,我覺得要先嘗試交流,相互交換,能融洽相容則最好啦,不能的話,及時終止。

2、客觀性的意見

客觀性的意見有如下幾種:筆誤(錯別字和其它疏忽)、代碼規範、知識性錯誤……

對於筆誤性的錯誤,這沒啥好說的,我自己發現過幾處,也被讀者指出過幾處。有則改之就好。

對於代碼規範,有時候為了舉例方便,確實沒有按照規範來。儘量避免,求一個兼顧。

知識性錯誤是要熱烈歡迎的——不是說歡迎錯誤,而是說歡迎別人來指出我所未知的錯誤。

出現知識性的錯誤,就意味著沒有全面掌握知識,一旦出現,就必然意味著有提升的空間。本來以為知道了什麼,如果被指出了錯誤,那改正後,才是真的知道了什麼。

知道自己不知道並且改正之,並不可恥,不知道自己不知道,這才可憐。

在寫《Python是否支持複製字元串呢?》的時候,我根據已得的知識,以及查閱到的資料,早早就得出了一個很滿意的結論。最後成文前,臨時地加了一個未作驗證的示例,沒想到這會是一個致命的反例,推翻了前面辛辛苦苦建立起來的一切。

這是一個客觀性的錯誤,一被指出的時候,很快就能驗證。因為這個錯誤,我重新梳理了相關的知識點,組成新的知識面,寫成了一篇《join()方法的神奇用處與Intern機制的軟肋》。

還有一個例子,前不久的《Python進階:自定義對象實現切片功能》,我在準備素材的時候,竟採用了一個不嚴謹的例子,而且自作聰明地批判了別人的實際無誤的例子。最後,有讀者留言了很長的不同觀點,我才意識到自己的錯誤!

得益於讀者的留言,我修正了自己的錯誤,而且在修正過程中,也加強了對於其它知識的理解,真是塞翁失馬焉知非福啊。

3、內置函數與內置類

這裡還有一個客觀性錯誤,藏得特別深,可能真的有 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 ,這意味著,以上兩種方法得要結合起來看。

我不確定有多少人事先知道怎麼區分內置函數與內置類,但我確實沒看到過對這個問題進行辨析的文章,所以,這次是真正漲知識了,也希望這篇文章,能夠消除一些讀者的錯誤觀念吧。

4、小結

我最近寫的一些文章都不是心血來潮,不管是字元串系列、切片系列還是迭代器系列,本意都是想在一個主題上進行深入的多面性的思考與記錄。

如果沒有一些熱心讀者的指正,我恐怕是很難知道自己錯在了哪裡,如果不是有這麼多的認同以及意見,我恐怕也缺乏動力堅持寫下去。

最後鳴謝幾位提意見的小能手同學(時間順序,可能有漏):@瘋琴、@德瑪西亞之翼奎因、@發條橙、@gaieepo、@郭芮、@aijam、@xpresslink、@進擊的糰子、@不換……

相關鏈接(單有錯,雙修正):

1、Python是否支持複製字元串呢?

2、join()方法的神奇用處與Intern機制的軟肋

3、Python進階:自定義對象實現切片功能

4、Python進階:全面解讀高級特性之切片!

5、為什麼range不是迭代器?range到底是什麼類型?

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

本文原創並首發於微信公眾號【Python貓】,後臺回覆“愛學習”,免費獲得20+本精選電子書。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 組合模式又叫做部分整體模式,適用於把一組相似的對象當作一個單一的對象。組合模式依據樹形結構來組合對象,用來表示部分以及整體層次 ...
  • 過濾器模式允許開發人員使用不同的標準來過濾一組對象,通過邏輯運算以解耦的方式把它們連接起來 ...
  • 1、併發的基礎 線程的基本概念 表示一條單獨的執行流,有自己的程式執行計數器,自己的棧 兩種創建方式:繼承Thread;實現Runnable介面 無論哪種創建方式最後都需要調用start方法啟動線程 synchronized 可用於修飾類的實例方法、靜態方法和代碼塊 多個線程可以同時執行同一個syn ...
  • 背景:需要調用第三方介面,開啟某項任務,用Hutool代替了HttpClient 調用第三方介面,簡單粗暴。 代碼如下:import java.util.Date;import org.apache.commons.lang.time.DateFormatUtils;import cn.hutool ...
  • age = 23 count=0 while count<3: guess_age = int (input("My age:")) if age ==guess_age: print("nice, you got it") break elif age < guess_age: print("gu ...
  • pycharm2018.3版 永久激活 如需轉發,請註明出處:小婷兒的python https://www.cnblogs.com/xxtalhr/p/10258257.html 激活前準備工作 · 激活前請先關閉pycharm · 修改配置文件的時候你需要填寫你的安裝路徑 · 如果出現修改配置文件 ...
  • 1 # ----------- 首字母大寫 ---------- 2 test = "alex is a man" 3 v = test.capitalize() 4 print(v): Alex is a man 1 # ----------- 轉換全部字元串為小寫 ---------- 2 te... ...
  • SpringMVC一.. SpringMVC重要組件介紹 1. DispacherServlet:前端控制器,接收所有請求,(如果配置/不包含jsp) 2. HandlerMapping:解析請求格式,判斷希望要執行哪個方法 3. HandlerAdapter:負責調用具體的方法 4. ViewRe ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...