有群友问过,是什么原因使我开始写技术公众号,又是什么动力让我坚持写的。

在我看来,写作是一件不能敷衍的事,通过写作来学习,反而要比单纯地学习的效果要好。为了写成一篇“拿得出手”的文章,我要反复查找资料,阅读与思考,拆解与整合,最终写成的时候,也是知识的拼图成型的时候。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

所以,对我来说,写作是一种咀嚼信息而后提炼知识,最终拓展成技能与认知的过程。虽然这个过程很缓慢,但曾经的急进方式并没有速成的效果啊,不妨就这样一文章一脚印地试试看咯。

除此之外,还有一个很重要的原因。文章是一种公共对话的媒介,它是一个展示的窗口,也是一个接收反馈的通道。通过写作,我有了跟其它学习者对话的机会。

看书学习可能只是个人的事情,但是,在写作平台上发布文章,这就超越了个人行为——你得随时准备着被批评、或者被请教、或者被误解、甚至是被无视(这是最常见的结果)。

我享受写作文章,来跟其他处在相同处境的同学们交流,来向更优秀的大牛们学习取经。

这就是我目前写技术文章的一些个人体会吧。

对于上面提到的第二个原因,我最近颇有感触,想要多聊一些。为了更有针对性,本文姑且限定一个话题吧,那就是“写作技术文章,如何看待他人的批评/意见”。

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 关键字加在构造方法前面概念更清楚一些。

根据这个评论,我就去查看文档。

聊聊技术写作的个人体会 Python 第1张

上图中 range() 虽然被归类到 Built-in Functions 里面,但是官方描述的是“functions and types”,即是说,在内置函数的大类下面,包含了内置函数与内置类。

那 range() 属于哪一种呢?看看它的解释:

Rather than being a function, range is actually an immutable sequence type……

range 实际是一种不可变的序列类型,而非一个(内置)函数……

按照这里的说法,官方已经区分了 range() 不是函数,正像那位留言的同学所说。

我第一反应当然是不能接受。我怎么会认为它是内置函数的呢,难道不是根据学习资料得来的么?难道我学习的资料是错的?为何从来没看到有人对此做过辨析呢?

根据群友的提示,我去查看 Python2 的文档,然后就发现了很有意思的地方:

聊聊技术写作的个人体会 Python 第2张

首先一点, 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+本精选电子书。

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄