有群友问过,是什么缘由使我开始写技术公众号,又是什么动力让我坚持写的。java
在我看来,写做是一件不能敷衍的事,经过写做来学习,反而要比单纯地学习的效果要好。为了写成一篇“拿得出手”的文章,我要反复查找资料,阅读与思考,拆解与整合,最终写成的时候,也是知识的拼图成型的时候。python
因此,对我来讲,**写做是一种咀嚼信息然后提炼知识,最终拓展成技能与认知的过程。**虽然这个过程很缓慢,但曾经的急进方式并无速成的效果啊,不妨就这样一文章一脚印地试试看咯。bash
除此以外,还有一个很重要的缘由。文章是一种公共对话的媒介,它是一个展现的窗口,也是一个接收反馈的通道。经过写做,我有了跟其它学习者对话的机会。微信
看书学习可能只是我的的事情,可是,在写做平台上发布文章,这就超越了我的行为——你得随时准备着被批评、或者被请教、或者被误解、甚至是被无视(这是最多见的结果)。函数
我享受写做文章,来跟其余处在相同处境的同窗们交流,来向更优秀的大牛们学习取经。学习
这就是我目前写技术文章的一些我的体会吧。ui
对于上面提到的第二个缘由,我最近很有感触,想要多聊一些。为了更有针对性,本文姑且限定一个话题吧,那就是“写做技术文章,如何看待他人的批评/意见”。spa
有些声音其实只是主观见解,我认为能够和而不一样。翻译
主观世界每每没有确切的对错之分,毕竟——思想无罪 。代码规范
面对主观性的意见,我认为要作到有理有据,坚持一点个性,最后会获得别人的尊重。
好比,在翻译 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+本精选电子书。