Python 开发中有哪些高级技巧?

我列出来几个,不知道算不算高级技巧,但是我个人觉得非常有用。1. 善用迭代器迭代器在很多语言里面都有,而在 Python 里适当的场景用迭代器会非常的“爽”。一来因为迭代器每次产生一个对象,适当使用能有效节省内存;二来它能达到部分“延迟计算”的效果。除此以外,因为 Generator (yield 关键字)和 Generator Expression 的存在,有时候使用迭代器能提升代码可读性。举例,itertools.islice((calculate_for_value(v) for v in values), 0, 12) 能够只在 [0, 12) 范围内计算,而且是延迟计算的,即迭代到了那个对象才去计算。又如 any(i % 3 == 0 for i in numbers) 能够找出 numbers 里第一个能被 3 整除的值,因为里面是个 Generator Expression(迭代器的一种),所以找出以后 any 函数就会立即返回,并不需要对整个 numbers 列表计算 i % 3。顺带推荐下这个库 erikrose/more-itertools ,里面包含了很多实用的迭代器函数,是对标准库 itertools 的一个很不错的补充。2. 善用描述符(Descriptor)Python 的描述符是对“属性”的抽象,一个描述符定义成类属性以后,能够控制这个类的实例上同名实例属性的 get、set、delete 行为,比 __getattr__ 这样的实例级 magic method 有更细的粒度,并且更容易复用。这个文档有简单的描述 Descriptor HowTo Guide ,可见 Python 的“实例方法”、@property 全由它实现,一些第三方库也有用到(例如 SQLAlchemy 的 Column、WTForms 的 Field 乃至 Python 3.4 新增的 enum.Enum 类型)。利用描述符特性,可以在业务代码中实现一些非常方便的定制,例如可以自己实现一个能缓存返回值的 cached_property(也可以不用自己实现,直接用 Werkzeug 的)。3. 尽量不要用反射技巧去 fight with language我个人的一个观点:用一门编程语言就应该入乡随俗,fight with language 的事情不要做太多为好。因为闭门造的轮子很难造圆,更何况站在语言使用者的层面去和语言的设计搏击实在很不自量力。问题问的是“高级技巧”,那么对于一个动态语言,反射当然算高级技巧的。可是我见过一些利用 Python 的反射来扫描出一些包中所有 .py 文件然后自动 import 包下的所有模块的。且不说这个做法破坏了 Python “模块即是命名空间” 和 lazy import 的设定,光是从“正确性”来说就有一堆问题。这个做法仅仅考虑到了模块文件系统中的场景,没考虑到可能模块在一个 zip 中的情况。就算再增强一下实现,考虑上 zip 的 import,那 Python 还有 PEP 302 定义的 Import Hook 用法呢,被这样一 hack 就完全没法用了。这种 fight with language 的做法很难去做到真正的“正确”。所以我觉得还有一个 Python 的技巧就是想使用“高级技巧”的时候谨慎地考虑使用。静下来想想自己是不是在 fight with language 了,如果是的话,建议停手。要不就入乡随俗,要不就认真考虑一下 Python 是不是真的有值得去改进的地方。后者是需要经过很多深思熟虑的,不是 10 分钟的想法就够。如果后者的回答真的是“是”,我想可能正确的做法是写一个 PEP 然后和社区讨论,看能否将改进直接施于 Python 未来的版本之上,而不是在自己的代码里用一个看似高级技巧实是丑陋的 hack 的实现来对抗语言本身。-------------------------------------------------------------------------------其他的一些 Python 特色的技巧,例如 decorator、contextmanager 等,因为各路 Python 开发者基本都很熟悉,我就没列出来了。-------------------------------------------------------------------------------补充下:其实这里有个超长列表 Hidden features of Python …… 不过里面的很多特性现在都是日常了-------------------------------------------------------------------------------2016-10-08 补充:来个真的有点高(黑)级(暗)的技巧吧,开发一个 stateful service 的时候怎么排障?比如出现死锁了,或者某个线程意外退出。这个时候可以从 gc.get_objects()

掏出所有活着的对象,其中当然就包括活着的线程。例如,打印出所有 Greenlet 的 stack:import os

import gc

import greenlet

import traceback

greenlets = [

o for o in gc.get_objects() if isinstance(o, greenlet.greenlet) if o]

stack = '\n\n'.join(

''.join(traceback.format_stack(o.gr_frame)) for o in greenlets)

open('/tmp/stack-%d.txt' % os.getpid(), 'w').write(stack)

这个方法结合 gevent.backdoor 堪称排障利器。如果愿意冒一定的风险,甚至可以使用调试器对事先没有埋过点的进程做活体检测——挂上 GIL 再打印一份线程 stack。详见 GitHub - wooparadog/pstack: Tool to dump python thread and greenlet stacks.

我个人觉得技巧没有大用, 关系是思想与概念。 学得越多,技巧忘记得越多, 简单的深刻的道理则会陪伴你一生。 我自己在python中,如果说技巧,就是教程上说的,list的那些用法, dict, defaultdict, collection, set,  array,  numpy, blist, event, socket,  cython, __init__, __all__, __doc__, keyerror还有些常用的库。 这些标准教程上的东西,你学会了,给自己帮助很大。 也都是技巧 。 偶尔用一用lambda, map, filter, zip就足够了。 可以缩小代码量。 多用multiprocess少用thread和threading。 有时间可以研究一下stackless python, twist,它的思想很受启发。 tornado, django, jinja2等都需要学一下,简单实用,强大。 最近流行的openstack也要看一下。zope这东西太古老了,如果你真有时间还是可以借鉴一下。 python2, python3都要学习。 不能一味抵制python3, 其中有很多好的思想。 GIL不是不可逾越的。 如果喜欢windows就学一学win32 api, 反之QT, wxwindows, gtk都可以看一看。 html5, node.js, javascript, bootstrap都是好的GUI工具。 要想快速开发, 很失望的说,只有在windows平台下可以找到可视化的快速开发工具。 C#, delphi, 都是很难超越的东西。python用得人多, 用好的人也多。 但是水准高,思想又好,编程也强大,可以创造性的做产品的人不多。 相反,模仿别人, 借鉴其它的库,拿来主义,这是python的特点。 swig这个东西学一学。以后你还会依赖其它的语言,需要的时候就多学一学其它的语言,甚至 ruby也是必要的。 java, c++, haskell, go, lua, javascript, php, scala. 但是有一天,python一定会衍生出不一样的版本。越超所有的语言,我相信。 但是不是最近。 这些所有的语言都没有挑战性。新的语言会带来新的设计模式。我们写Python代码的时候经常将一系列操作放在一个语句块中,Python 2.5加入了with语法,实现上下文管理功能,这让代码的可读性更强并且错误更少。最常见的例子就是open,如果不使用with,使用open会是这样:如果使用with,可以简化为两行:在执行完缩进的代码块后会自动关闭文件。创建上下文管理器实际就是创建一个类,添加__enter__和__exit__方法。看看如何实现open的上下文管理功能:自定义上下文管理器确实很方便,但是Python标准库还提供了更易用的上下文管理器工具模块contextlib,它是通过生成器实现的,我们不必再创建类以及__enter__和__exit__这两个特殊的方法:yield关键词把上下文分割成两部分:yield之前就是__init__中的代码块;yield之后其实就是__exit__中的代码块;yield生成的值会绑定到with语句as子句中的变量(如果没有生成,也就没有as字句)。2. total_ordering 。对比自定义对象需要添加__lt__、__le__、__gt__、__ge__和__eq__等方法,如果使用total_ordering,只需要定义__eq__以及__lt__、__le__、__gt__、__ge__四种之一就可以了:3. 有时候BUG隐藏的太深,需要对上下文都有清晰的展示来帮助判断。用pdb调试不方便,用print不直观。可以使用如下函数获取当前调用栈:4. inspect 。有时候我们想查看一下对象的一些信息或者做类型检查,也就是自省(检查某些事物以确定它是什么、它知道什么以及它能做什么):它在实际工作中还能有什么意义,通过自省获取方法的参数,从而设置缓存的键,如 flask-cache( https://github.com/thadeusb/flask-cache/blob/master/flask_cache/__init__.py#L418)和 douban-mc(https://github.com/douban/douban-mc/blob/master/douban/mc/decorator.py#L39)5. Mixin模式 。它是什么先看「Mixin是什么概念? 」 写Python代码的时候经常将一系列操作放在一个语句块中,Python 2.5加入了with语法,实现上下文管理功能,这让代码的可读性更强并且错误更少。最常见的例子就是open,如果不使用with,使用open会是这样:如果使用with,可以简化为两行:在执行完缩进的代码块后会自动关闭文件。创建上下文管理器实际就是创建一个类,添加__enter__和__exit__方法。看看如何实现open的上下文管理功能:自定义上下文管理器确实很方便,但是Python标准库还提供了更易用的上下文管理器工具模块contextlib,它是通过生成器实现的,我们不必再创建类以及__enter__和__exit__这两个特殊的方法:yield关键词把上下文分割成两部分:yield之前就是__init__中的代码块;yield之后其实就是__exit__中的代码块;yield生成的值会绑定到with语句as子句中的变量(如果没有生成,也就没有as字句)。2. total_ordering 。对比自定义对象需要添加__lt__、__le__、__gt__、__ge__和__eq__等方法,如果使用total_ordering,只需要定义__eq__以及__lt__、__le__、__gt__、__ge__四种之一就可以了:3. 有时候BUG隐藏的太深,需要对上下文都有清晰的展示来帮助判断。用pdb调试不方便,用print不直观。可以使用如下函数获取当前调用栈:4. inspect 。有时候我们想查看一下对象的一些信息或者做类型检查,也就是自省(检查某些事物以确定它是什么、它知道什么以及它能做什么):它在实际工作中还能有什么意义,通过自省获取方法的参数,从而设置缓存的键,如 flask-cache( https://github.com/thadeusb/flask-cache/blob/master/flask_cache/__init__.py#L418)和 douban-mc(https://github.com/douban/douban-mc/blob/master/douban/mc/decorator.py#L39)5. Mixin模式 。它是什么先看「Mixin是什么概念? 」 写Python代码的时候经常将一系列操作放在一个语句块中,Python 2.5加入了with语法,实现上下文管理功能,这让代码的可读性更强并且错误更少。最常见的例子就是open,如果不使用with,使用open会是这样:如果使用with,可以简化为两行:在执行完缩进的代码块后会自动关闭文件。创建上下文管理器实际就是创建一个类,添加__enter__和__exit__方法。看看如何实现open的上下文管理功能:自定义上下文管理器确实很方便,但是Python标准库还提供了更易用的上下文管理器工具模块contextlib,它是通过生成器实现的,我们不必再创建类以及__enter__和__exit__这两个特殊的方法:yield关键词把上下文分割成两部分:yield之前就是__init__中的代码块;yield之后其实就是__exit__中的代码块;yield生成的值会绑定到with语句as子句中的变量(如果没有生成,也就没有as字句)。2. total_ordering 。对比自定义对象需要添加__lt__、__le__、__gt__、__ge__和__eq__等方法,如果使用total_ordering,只需要定义__eq__以及__lt__、__le__、__gt__、__ge__四种之一就可以了:3. 有时候BUG隐藏的太深,需要对上下文都有清晰的展示来帮助判断。用pdb调试不方便,用print不直观。可以使用如下函数获取当前调用栈:4. inspect 。有时候我们想查看一下对象的一些信息或者做类型检查,也就是自省(检查某些事物以确定它是什么、它知道什么以及它能做什么):它在实际工作中还能有什么意义,通过自省获取方法的参数,从而设置缓存的键

其实python非常适合初学者入门。相比较其他不少主流编程语言,有更好的可读性,因此上手相对容易。自带的各种模块加上丰富的第三方模块,免去了很多“重复造轮子”的工作,可以更快地写出东西。配置开发环境也不是很复杂,mac和linux都内置了python。另外据我所知,不少学校也开始使用python来教授程序设计课程(比如本人的母校)。我就是完全通过网上资源自学python的。从在校时候用python接活赚零花钱,到在创业公司用python开发商业网站和游戏后台。所有遇到的问题,几乎都可以从互联网上的公开资源找到答案。关于自学python,个人最大的3点经验:找一本浅显易懂,例程比较好的教程,从头到尾看下去。不要看很多本,专注于一本。把里面的例程都手打一遍,搞懂为什么。我当时看的是《简明python教程》,不过这本书不是非常适合零基础初学者。去找一个实际项目练手。我当时是因为要做一个网站,不得已要学python。这种条件下的效果比你平时学一门新语言要好很多。所以最好是要有真实的项目做。可以找几个同学一起做个网站之类。注意,真实项目不一定非要是商业项目,你写一个只是自己会用的博客网站也是真实项目,关键是要核心功能完整。最好能找到一个已经会python的人。问他一点学习规划的建议(上知乎也是个途径),然后在遇到卡壳的地方找他指点。这样会事半功倍。但是,要学会搜索,学会如何更好地提问。没人愿意帮你写作业或是回答“一搜便知”的问题。然而,别人的经验未必能完全复制。比如我没有说的是,在自学python之前,我已在学校系统学习过其他的编程语言。对于完全没有编程经验的初学者,在学习python的时候,面对的不仅仅是python这门语言,还需要面临“编程”的一些普遍问题,比如:从零开始,不知道从何入手,找了本编程教材发现第二章开始就看不懂了缺少计算机基础知识,被一些教程略过的“常识性”问题卡住遇到问题不知道怎么寻找解决方案看懂语法之后不知道拿来做什么,学完一阵子就又忘了缺少数据结构、设计模式等编程基础知识,只能写出小的程序片段所以除了前面说的3点经验,给初学编程者的额外建议:首先要有信心。虽然可能你看了几个小时也没在屏幕上打出一个三角形,或者压根儿就没能把程序运行起来。但相信我,几乎所有程序员一开始都是这么折腾过来的。选择合适的教程。有些书很经典,但未必适合你,可能你写了上万行代码之后再看它会比较好。写代码,然后写更多的代码。光看教程,编不出程序。从书上的例程开始写,再写小程序片段,然后写完整的项目。除了学习编程语言,也兼顾补一点计算机基础,和英语。不但要学写代码,还要学会看代码,更要会调试代码。读懂你自己程序的报错信息。再去找些github上的程序,读懂别人的代码。学会查官方文档,用好搜索引擎和开发者社区自己多问下为什么学python      如果一门语言没有改变你的编程思维,那么它不值得你去学习”。如果这么说,我们大学的时候,学习了c,c++,java,C#,算是值得学习么?很多时候是不值得,我觉得我们大学的课程就是用java,c#,c++把"C程序设计"又上了一遍.    这是因为,学校的老师会C和java之类的,所以要跟着规矩开这门课,(这也就是为什么,许多学校还在教vb,),这也就是为什么,你所以为的一样就是大家都有For都有while,都有switch..都有Class...都有int 都有float,所谓的不一样就是用C有指针,java没有,这就是为什么教育是失败的,这也就是为什么,我目前认识的几个编程大牛    python的优点:简单 我所说的简单,是相比于象C和C++这样的语言,你为了编程,要学习许多偏底层的东西.在比如,你在学习一个新的编程范式,或者想要马上做个例子看看,试验某个API,如果你是写java的,你不得不去写一个main,写一些构造,即使有IDE这样的东西,能够为你带来代码生成器,而我做得就是写一段“脚本”,或者打开python交互式解释器就行了。  自己认识的python朋友出去工作,工资比较高,然后自己又刚刚好是会python所以选择学习python,这样的人比较危险但是也比较有激励,还有就是觉得python比其他开发语言好用。学完python前景会咋样  其实我个人是很看好python未来的就业前景的,因为我认识太多的工程师都已经在学python,很多都是月收入大几万的    我个人也并非一直用python。前些年主要用c/c++以及java开发一些通信,移动系统,互联网通信。近3年开始才转向python。坦白的说,这可能与你相处的公司以及环境不大一样。随便举个例子,google的protocol buffer协议一出来就具有c++/python/java三种语言支持。google的广告系统早在03,04年左右就一并对python进行了webservice支持,大部分涉及基础核心系统的公司,都开始对python进行了扩展支持。甚至开源社区的postgresql数据库,除了自身的ansi SQL,pgsql,pg/TCL,PG/PERL之外对python进行了内嵌支持,唯独却没有呼声很高的java。在FREEBSD(MIT)/LINUX(GPL)平台上,对java可能排斥性比较大,但综合而言,目前python发展还没有java那种普及,主要是python大部分工作仍然是在较为深入地系统层和框架层做设计开发,例如django,SQLAlchemy,fail2ban,mail邮件系统,twisted等等。这部分对于那种习惯应用前辈们框架的编码人员而言,缺乏创造力的他们根本无法适用这种开发。尤其在python涉及一些系统层面需要有较强的c/c++能力,这部分人在国内要么就累得要死没时间,要么就啥都不会就会拷贝代码,而国内公司也鲜有主动去做这部分基础劳动的,大多都是等别人做好了在直接拿来用,所以造就了任何技术性的东西出来,国内都是先等等看,然后抄袭应用。    大环境如此,但千万误认为先等等看吧。对于一个技术人员而言,缺乏对新技术的渴望与热情,这是一种非常危险的事情。我工作8年了,按照国内很多的人的说法早已不做代码了,但又一次在听一个老外的演讲,他说他50多岁仍然每天坚持写代码,了解最新的动态,所以他才能做到他们公司的首席科学家,因此它才能时刻指导项目团队前进并保证项目的质量。他坦言对于一个不写代码并且不了解最新的技术动态的技术人员或者技术团队的负责人而言,这种团队也就足够做作小项目,一旦压力和项目过大,就会有很多问题漏出来。  对于新人而言,无论学习什么技术,都要以鼓励的姿态出现。太多用薪水和你个人所看到的现状去衡量一门技术,那绝对是欠缺眼光的。任何一门技术,一旦有人学习,他有可能逐渐成为这个领域的专家,即便再滥再没有人用的开发语言技术,他也有可能就是明日的奠基者或者大师。最后:自己如何确定目标 在生活中学会不断挖掘自己的潜力。我们都是一个普通人,可能并不清楚自己到底在哪方面占有优势。所以,学着在生活中找到自己的优势,并根据优势选择一定的就业方向。 不随波逐流。不要看周围的人做什么,自己就做什么,也许别人做的并不适合你。别人的优势很可能会成为你的劣势。所以,坚定自己的想法,让自己知道那些方面适合自己,自己可以胜任。  不断尝试可能成为自己的优势。你不知道什么适合自己,所以才要大胆、勇敢地尝试。找到一种可以属于你的独特的优势。 坚定信念。一旦你坚定了自己的信念,就不要被别人的意见或是讽刺或是嘲笑所干扰。别人不是你,不懂的你在想什么,不清楚你开始这件事的源头。你的事情,不了解你的人,没有资格轻易评说。  不茫然,不多想。别让太多的事干扰到你奋斗下去的信念。梦想不容许太多的杂念。那些杂念只会让你的心愈来愈脆弱,多为一个人考虑,到头来,伤害的还是自己。选择自己学习方法  每个人都有适合自己的方法,有的人去选择自学,有的人选择看视频学习,有的人选择报名培训班,那在这个时候,你就要自己考虑清楚,到底那样对的帮助是最大的,个人觉得是跟着培训班最好的,毕竟人家的实战项目多,我们学软件开发的都知道实战项目对于学好一门语言是 很重要的。学习python有那些误区具体里面的误区非常的多,那些就不需要我去写出来,我给你说的一般都是心态的问题,首先一个觉得自己会java和c++,然后我学习python就很牛,但是你要知道语言是有很多相同的地方,但是不是通用,一定要自己学习的仔细。还有一种就是觉得我不会英语,我要先去把英语学习好在来学python。因为自己想还坏主意然后学习,这样的都是容易找进误区的。怎么样才能学好python  学好python你需要一个良好的环境,一个优质的开发交流群,群里都是那种相互帮助的人才是可以的,我有建立一个python学习交流群,在群里我们相互帮助,相互关心,相互分享内容,这样出问题帮助你的人就比较多,群号是304050799,这样就可以找到大神聚合的群,如果你只愿意别人帮助你,不愿意分享或者帮助别人,那就请不要加了,你把你会的告诉别人这是一种分享。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容