Python 从业十年是种什么体验?老程序员的一篇万字经验分享!

我“接触” Python 已有十年了,当初我们要做一个网站,有个学弟只花两天,就用 Django 开发好了后台。那是我第一次感受到了 Python 的强大魅力。不过,我正式学习和使用它,才仅有两年时间……

 

标题中说的“从业十年”,并不是指我,而是指文章的作者。像他拥有这么长的 Python 经验的程序员并不多见,写成文章分享出来的就更少见了。所以这篇文章还挺有价值的,内容很丰富,特分享给大家,建议收藏。

 

一、概述

本文起源于我在 Twitter 上发布的关于 Python 经历的一系列话题。

出于某些原因,想记录一下我过去数年使用 Python 的经验和一些感悟。毕竟算是一门把我带入互联网行业的语言,而我近期已经几乎不再写 Py 代码, 做一个记录,也许会对他人起到些微的帮助,也算是纪念与感恩了。

二、摘录

推文地址:https://twitter.com/ppcelery/status/1159620182089728000


最早接触 py 是 2010 年左右,那之前主要是使用 c、fortran 和 matlab 做数值运算。当时在做一些文件文本处理时觉得很麻烦,后来看到 NASA 说要用 py 取代 matlab,就去接触了 py。

python 那极为简洁与优美的语法给了当时的我极大的震撼,时至今日,写 py 代码对我而言依然是一种带有艺术意味的享受。

私信博主001 领取完整代码!

 


首先开宗明义的说一句:python 并不慢,至少不够慢。拿一个 web 后端来说,一台垃圾 4 核虚机,跑 4 个同步阻塞的 django,假设 django 上合理利用线程分担了阻塞操作,假设每节点每秒可以处理 50 个请求(超低估),在白天的 10 小时内就可以处理 720 万请求。而这种机器跑一天仅需要 20 块钱。

Python 从业十年是种什么体验?老程序员的一篇万字经验分享!_第1张图片


在学习 Python 以前需要强调的是:基础语法非常重要。虽然我们都不推崇过多的死记硬背,但是少量必要的死背是以后所有复杂思维活动的基础,就像五十音对于日语,通假字和常用动名词对于文言文,你不会就是不行。

 

一般认为,这包括数据类型(值/引用)、作用域(scope)、keyword、builtin 函数等


关于 Python 版本的选择,很多公司老项目依然在用 2.6、2.7,新项目的话建议至少选择 3.6(拥有稳定的 asyncio)。

  • 从 2.7 到 3.4 https://blog.laisky.com/p/whats-new-in-python3-4/
  • 从 3.4 到 3.5 https://blog.laisky.com/p/whats-new-in-python3-5/
  • 从 3.5 到 3.6 https://blog.laisky.com/p/whats-new-in-python3-6/
  • 从 3.6 到 3.7 https://docs.python.org/zh-cn/3/whatsnew/3.7.html

关于版本最后在说几点,建议在本地和服务器上都通过 pyenv 来管理版本,而不要去动系统自带的 python(以免引起额外的麻烦) https://blog.laisky.com/p/pyenv/

另外一点就是,如果你想写一个兼容 2、3 的工具包,你可以考虑使用 future http://python-future.org/compatible_idioms.html

最后提醒一下,2to3 这个脚本是有可能出错的。


学完基础就可以开始动手写代码了,这时候应该谨记遵守一些“通行规范”,几年前给公司内分享时做过一个摘要:

  • 风格指引 https://laisky.github.io/style-guide-cn/style-guides/source-code-style-guides/
  • 一些注意事项 https://laisky.github.io/style-guide-cn/style-guides/consensuses/

有了一定的实践经验后,你应该学习更多的包来提高自己的代码水平。

  • 值得学习的内建包 https://pymotw.com/3/
  • 值得了解的第三方包 https://github.com/vinta/awesome-python

因为 py 的哲学(import this)建议应该有且仅有一个完美的方式做一件事,所以建议优先采用且完善既有项目而不建议过多的造轮子。

Python 从业十年是种什么体验?老程序员的一篇万字经验分享!_第2张图片


一个小插曲,写这段的 Tim Peters 就是发明 timsort 的那位。

https://en.wikipedia.org/wiki/Tim_Peters_(software_engineer)


有空时候,建议尽可能的完整读教材和文档,建立系统性的知识体系,这可以极大的提升你的眼界和思维能力。我自己读过且觉得值得推荐的针对 py 的书籍有:

  • https://docs.python.org/3/
  • learning python
  • 核心编程
  • 改进Python的91个建议
  • Python高手之路
  • Python源码剖析
  • 数据结构与算法:Python语言描述

如果你真的很喜欢 Python 的话,那我觉得你应该也会喜欢阅读 PEP,记得几年前我只要有空就会去翻阅 PEP,这相当于是 Py 的 RFC,里面记录了几乎每一项语法的设计理念与目的。我特别喜欢的 PEP 有:

  • 8
  • 3148
  • 380
  • 484 & 3107
  • 492: async
  • 440
  • 3132
  • 495 你甚至能学到历史知识

Python 从业十年是种什么体验?老程序员的一篇万字经验分享!_第3张图片


以前听别人讲过一个比喻,静态语言是吃冒菜,一次性烫好。而动态语言是涮火锅,吃一点涮一点。

那么我觉得,GIL 就是仅有一双筷子的火锅,即使你菜很多,一次也只能涮一个。

但是,对于 I/O bound 的操作,你不必一直夹着菜,而是可以夹一些扔到锅里,这样就可以同时涮很多,提高并行效率。


GIL 在一个进程内,解释器仅能同时解释执行一条语句,这为 py 提供了天然的语句级线程安全,从很多意义上说,这都极大的简化了并行编程的难度。对于 I/O 型应用,多线程并不会受到多大影响。对于 CPU 型应用,编写一个基于 Queue 的多进程 worker 其实也就是几行的事。

(订正:应为伪指令级的线程安全)

from time import sleep
from concurrent.futures import ProcessPoolExecutor, wait
from multiprocessing import Manager, Queue


N_PARALLEL = 5


def worker(i: int, q: Queue) -> None:
    print(f'worker {i} start')
    while 1:
        data = q.get()
        if data is None:  # 采用毒丸(poison pill)方式来结束进程池
            q.put(data)
            print(f'worker {i} exit')
            return

        print(f'dealing with data {data}...')
        sleep(1)




def main():
    executor = ProcessPoolExecutor(max_workers=N_PARALLEL)  # 控制并发量
    with Manager() as manager:
        queue = manager.Queue(maxsize=50)  # 控制缓存量

        workers = [executor.submit(worker, i, que

你可能感兴趣的:(Python,Python)