你好,我是一名python初学者,我想问一下膜法师是什么梗,有哪些书是有用的,适合我!

大家都在搜:李久凯律师
微信扫一扫 免费问律师
手机扫一扫 法律兜里装
&&内蒙古咨询&&&
律师,你好,我是内蒙的,我想问一下
律师,你好,我是内蒙的,我想问一下,我家楼上的没装修,是个毛坯房,就把房子租出去了,天天声音听的特别清楚,我们应该怎么样来通过法律手段来让他们搬出去
来自移动端
158****6394|
内蒙古&通辽|
房屋买卖咨询
1分钟提交法律咨询 2000多位 信的过的好律师 为您提供专业解答
其他人都在看
吉安房屋买卖律师
解答个咨询
擅长,个相关案例
房屋买卖最新问题:
相关法律咨询
热门房屋买卖法律百科
房产证是指购房者通过交易,取得房屋的合法所有权,可依法对所购房屋行使占有、使用、收益和处分的权利的证件。在房产证上加名字的手续,加名字是否有用。
房屋买卖相关知识
房屋买卖最新专题
律师365,优质法律服务平台
400-64365-00
服务时间:周一至周六8:00~22:00
||||网站地图|
Copyright(C) 成都六四三六五科技有限公司 版权所有 蜀ICP备号
扫描二维码
更多惊喜等着您!你好,我是初学者,我想问一下写歌词该怎么写_百度知道我是Python程序员,你们有什么想问的吗?
194回复/3亮 16404浏览
引用64楼 @ 发表的:
python一般作为程序员的第二语言或者脚本语言,你是怎么想把它作为你的主要技术栈的?
1.不喜欢Java。
2.我待的城市似乎没有比较合适的C++机会。(后来发现其实有)
3.对现在的工作内容挺满意,而且不加班。
引用49楼 @ 发表的:
软件工程的课程没有对应什么计算机语言了吧?
没有,都是自学的。
引用56楼 @ 发表的:
php是世界上最好的语言,你服不服?
不服。虽然我也不会也不想学PHP。
引用66楼 @ 发表的:
c#就业前景如何
不好,很差,至少国内很差。
引用72楼 @ 发表的:
你确定?现在还是java的天下吧
其实他说的那两个方向用Python的挺多的,至少不比Java少吧。
引用74楼 @ 发表的:
楼主,用vim呀
我对编辑器没有什么特别嗜好。
引用76楼 @ 发表的:
介绍本进阶的书吧……先谢
Python Cookbook
High Performance Python
Python源码剖析
引用77楼 @ 发表的:
问点无关的,我学物流管理,必修C#,根本听不懂,求问怎么自学或者有什么好方法
不太清楚你的具体情况,我给一个不能确保有效但你可以尝试的方法,一边看书,一边试着把书上的代码都照着敲下来执行。
引用79楼 @ 发表的:
我只有在生物信息学听过,你们还能做其他的吗?
除了操作系统应该都能写。
引用81楼 @ 发表的:
请问学J2ee怎么转过去学PYTHON?
如果是写Java的应该不会问这样的问题吧?
熟悉语法和常用框架,然后开始写就是了。
引用83楼 @ 发表的:
Python 不是应用性很强么,引用的库很丰富,做算法大多用Python,楼主具体是用来做啥?
后端开发。
引用89楼 @ 发表的:
我想今年考个研究生做中文语言处理,暂定北京语言大学,楼主请问现在做数据工程师进bat难度大吗?我是文科生……
我不是BAT的,而且只熟悉Python想进BAT很难。
不是混过来的话,NLP挺好找工作的,不过我觉得职业规划不一定非要以进某某公司为目标。
引用82楼 @ 发表的:
我在自学python.. 希望毕业的时候多点python的工作吧
不是学历比较硬的话,建议至少熟悉下C++或者Java。
引用67楼 @ 发表的:
那么这个薪资具体大概是什么水平?想有个参考
我觉得可以参照Java开发的水平。不过Python岗位达到30k/月后再涨会比Java难。
引用69楼 @ 发表的:
Python 的gil问题影响大吗?最新的解决方案是什么?stackless Python一般用什么
1.大。
2.IO密集型需求比较常见的解决方法是Tornado或者gevent,如果任务处理时间比较长可以用消息队列。至于CPU密集型需求……你或许压根不应该用Python。
引用93楼 @ 发表的:
现在是运维,想做python后端开发,lz指点下方向。python基本功还算可以,还需要学一些什么?公司里可以提供这个岗位,现在部门也可以提供练手的项目。
web后端吧,熟悉下Django/Flask/Tornado这些。不想写web的话估计只能去一些以Python技术栈为主的中型互联网公司了。
引用94楼 @ 发表的:
楼主本科都学了那些语言啊,我也是学软工的,想了解一下
比较熟悉的是Python和C++(半吊子水平)。
引用96楼 @ 发表的:
现在web前端是不是不好找工作啊
对比写java后台
你说的这两个需求都挺大的,而且可能是需求最大的两个。
引用98楼 @ 发表的:
楼主,我现在是大学生,主攻PHP+MYSQL的后台部分。前台HTML和CSS也有在做,
未来主攻JAVA,能不能跟我讲件这几个语言的市场需求啊
Java和web前端都很好找工作,PHP比这俩行情稍差些且工资低些。
引用101楼 @kirazjy 发表的:
python学到什么程度就能找工作了呢? 学完python再去学java有用吗?再学第二门语言时间是不是短很多?谢谢
1.第一个问题还真不好回答,或许你可以用Python做几个网站的时候吧。
2.有用这个词怎么理解?
3.会有帮助,但是Python缺少Java里的很多概念。先学Java/C++再学Python会觉得容易上手,反过来可能不一定。
引用102楼 @如洗de日子 发表的:
30k每月。。。都超步行街平均水平了,不用以后了,够了!
其实我建议改行的人不要用Python找工作。因为真的很不好找。
引用104楼 @B老公 发表的:
python 怎么会是小众呢?我一个金融狗都要用……
你会用Python但你不是Python程序员。
引用105楼 @Air_Jordan_23 发表的:
我很喜欢python。这货的前途在爬虫,数据挖掘,以及脚本这块,工程性差java太多。
java废话多,但架子搭好了可以大把大把用猪队友。
你说得对,Python适合小团队搭建原型,项目大了重构不容易。为了避免各种奇怪问题,我们组招人门槛不太低。可就是因为不太好招人,我司其他部门也慢慢转移到Java上了。
引用108楼 @Air_Jordan_23 发表的:
还有,入门肯定是learn python the hard way啊。
另外flask的文档很不错。
入门看哪个都差不多。因为入门教材基本都没什么深度。
引用110楼 @tim在路上 发表的:
最好的编程语言是什么
不是PHP。
引用116楼 @RealSainty 发表的:
平时一直用的python,也用来做做自己想做的东西,但是因为python工作机会小的原因,目前还带着看看C++。问一下楼主,python你当时都找了哪些公司?目前想呆的地方是苏州杭州或者南京这边吧
苏州南京似乎都不太好找Python的机会。杭州的话阿里和网易有部分偏运维开发的组在用。总的来说都不好找,因为你面试的时候不一定能碰到写Python的组的面试官。
引用117楼 @2pac2010 发表的:
楼主你好,我零基础自学python一个多月了,现在在学习django和flask,感觉python学习中不需要动脑的地方很多,于是萌生了学习c/c++/java的想法,求教下楼主应该选择什么方向?(时间有限所以才会这样问)
互联网这块,C机会少,C++要求高。不知道学什么就学Java吧,起码工作好找。
如果你跟我一样不想写业务的话,我推荐C++。当然这是一条hard way,入坑前先想好。
引用118楼 @乙烯啦啦啦 发表的:
大三,最近在自学廖海峰老师的教程,快看完了,准备写一点东西了。我是准备毕业找Python的工作的,楼主你这么一说,我又想转Java了啊…楼主大哥提下意见啊PS:大二做过Android的项目,坐标帝都
写Android不是很好吗?话说现在大三的话应该已经开始找实习了吧,这个过程中你没发现Python不好找吗?
引用124楼 @2pac2010 发表的:
我还开始入门flask.
之前的学习感觉没有太多c语言那种要去思考机器底层的东西(我只在大二上过一门c语言课)
大学生不建议急着做项目,建议先把基础打牢,尤其是操作系统这块。
本科一般的操作系统教材讲的都太浅了,有些讲内核的书也没有你以为的那么高大上,都挺深入浅出的,可以自己找来看看,进程管理内存管理文件系统这块略深入了解下对你之后很有帮助。另外推荐下《深入理解计算机系统》。
引用126楼 @MK追风少年 发表的:
普通一本大学,学的物联网,只会打球,0基础不过对电脑挺感兴趣,c语言,java什么的感觉不难,大三了,求指路方向
好好学Java,做点项目,找个实习。具体怎么做网上搜搜经验帖比听我扯淡靠谱。
引用127楼 @窟莉for3 发表的:
新上手的jr求问,客户端开发是指安卓开发吗
iOS和安卓都算。
引用131楼 @梦回长桥 发表的:
一般来说,外行想要对程序有一定了解,至少不是一脸懵逼,需要做到什么程度啊
听我吹牛没有用,你必须先自己写一个出来才能有点概念。
引用133楼 @那裤子厉害咯我 发表的:
自学入门有什么书或者网站吗
引用134楼 @乙烯啦啦啦 发表的:
我们班主任告诉我们写Java,Android什么的没前途…我是真的不知道怎么搞了…现在大三下,C++只懂皮毛,再重新学肯定来不及了;我现在就想学学Java或者Python,然后暑假去找实习;主要是Java也是半吊子,就是当时做Android项目的时候自学的,也没用Java做过什么;然后Android也是自学的,只是项目中的小角色,主框架不是自己写的,只会写点简单的界面,数据库也是用的leancloud…我就想着这学期好好搞定一门简单的语言然后能做出小东西接着去实习,这就想到学Python了…感觉本科实在是过得太水了,想要工作好好努力
引用135楼 @VvlvV 发表的:
求书籍进阶介绍,本人大三,目前网易游戏实习,需要搞Python
请看主楼更新。
引用141楼 @将军干一休 发表的:
你觉得python之父和王垠谁比较牛逼
都比我牛逼。
引用143楼 @绿萝月 发表的:
求问数据挖掘统计模型之类的 python有什么入门书推荐吗 一直用R的内牛满面
不过我没看过。
引用144楼 @Tabthe7 发表的:
想诚心问楼主,python学到什么程度就可以去找公司面试拿offer了呢?大概地指导下我,要会写什么样的算法、能独立实现什么样的功能吧;另外,如果你懂python的数据挖掘,也请讲讲?先谢过了
每个公司岗位面试官要求都不一样,不如自己先去面试几次,跟面试官聊聊,招聘信息上的职位需求也是参考。
引用145楼 @olivershnn 发表的:
python怎么可能不聪明。。支持cpp混写,很多诡异的东西都能搞出来啊
你这里说的诡异怎么理解?另外混合编程用C的更多。
引用154楼 @那时闪电 发表的:
现在语言编程,程序员是不是有点人才过剩的感觉啊,计算机专业学生表示求出路,学什么前景比较好呢
不过剩,优秀人才一直都急缺。学什么请参考我主贴更新。
引用156楼 @sail2000 发表的:
对我头像怎么看?
原谅我不知道这是什么……
引用157楼 @刘照福 发表的:
任何语言学精都非常难,尤其是Java和c++体系太过于庞大。
Scala和C++不是同一种复杂。
引用158楼 @德隆威廉姆欺 发表的:
那我学C#用处是不是很小
技术无高低,但C#在国内的就业市场很小。
引用163楼 @dsyy0326 发表的:
最近在逛joinquant论坛,主题偏量化交易的,想问下LZ,如果用python来写量化的话,相对于其他语言的优势在哪,然后这种高频的tick写脚本策略有哪些需要注意的地方呢
不是计算密集型需求所以可以用脚本语言,Python又是脚本语言里最易学的。问题二因为不了解就没法回答了。
引用164楼 @心脏的火药 发表的:
楼主圣诞节一般干嘛…
该干吗就干吗。我不但圣诞节不加班,平时也不加班。
引用165楼 @枪林恋曲 发表的:
楼主,我是看了知乎很多人都推荐学python入门编程,然后我就零基础开始自学python,感觉确实比较容易上手,目前可以写一些爬虫,做一些数据分析。可以用django搭建简单的网站。
目前已经下定决心转编程了,坐标深圳,下个月会离职专心自学。方向是从python web入手,不过听你一说不建议通过python找工作,有点尴尬啊。。。。
既然已经开始学了,不如先做点东西再投简历试试。
引用172楼 @ 发表的:
谢啦。我对编程是0基础。正在慢慢的运维转管理和项目管理。对编程要求不是很高。但是有几个Excel表格和老的Access数据库想转成SQL数据库+Web登陆管理。请问可以实现么?难度高么?每天自学1小时左右的话,大概需要多少时间能学费Python?
可以。难度不高。多久能学会这个得看基础和悟性吧,不好一概而论。
引用187楼 @ 发表的:后端的以后不转架构有啥前途?
前段牛逼才是真牛逼。。
不是我歧视前端程序员,但我觉得前端真没啥技术含量。
您需要登录后才可以回复,请
& 允许多选
133人参加识货团购168.00元30人参加识货团购245.00元77人参加识货团购308.00元224人参加识货团购485.00元26人参加识货团购119.00元46人参加识货团购339.00元11人参加识货团购125.00元69人参加识货团购720.00元253人参加识货团购698.00元88人参加识货团购128.00元50人参加识货团购438.00元热门关键字:
当前位置:
&&已解决&&&&&&&&&&
问题描述咨询者:杭银杏
你好,我想问一下报考公务员需要看哪些书呀
管理员解答好评率:100%
您好,用公务员考试一本通Python 有哪些优雅的代码实现?
有哪些优雅的代码实现 ?以前在一篇博客中学习过。记得这是有一个统一的名称的。不过忘了举个常用的例子
not…… ]。这种代码写的很爽,但感觉自己掌握的不全。所以特来问一下
按时间排序
下面的代码大概也算不上优雅。以下代码在python3中实现更多内容可见:lambda函数的使用lambda,又称匿名函数。当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便。比如命名一个普通的函数:def f(x):
return x * x
在这里,f为函数名,x是函数的参数,x*x则是函数的返回结果。我们可以换成lambda的形式则是:&&& lambda x : x*x
&function &lambda& at 0x7fa2d1298048&
&&& f = lambda x : x*x
lambda函数有一个限制就是函数中只能有一个表达式(事例中的x*x),该表达式的结果即是返回值。当然这个表达式可以用下面的一些技巧写的更“优雅”一些。其中lambda函数返回是一个对象,其实在python中,绝大部分的都是对象,函数也是对象。所以我们能将lambda函数赋给其它对象(事例中的f)。但是不建议这么做。一般使用lambda表达式时要注意:1.逻辑简单,切忌在一个lambda表达式中做出很复杂的逻辑,这么做可能感觉逼格很高但是代码的可读性会变得非常差。2.一次性使用,就像上面所说的不建议使用f = lambda
x:....的形式map,reduce,filter函数的使用map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。比如我们有一个函数f(x)=x2,要把这个函数作用在一个list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()实现如下:&&& def f(x):
return x * x
&&& r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
&&& list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
其中注意,传进map()的第一个参数是 f 而不是f(),其中f表示的是f函数对象本身而f()则是对函数f的调用。map()作为高阶函数,事实上它把运算规则抽象了,因此,我们不但可以计算简单的f(x)=x2,还可以计算任意复杂的函数,比如,把这个list所有数字转为字符串:&&& list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
['1', '2', '3', '4', '5', '6', '7', '8', '9']
当然,map()中还可以传入lambda表达式:&&& list(map(lambda x: x*x,range(10)))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
或者再结合一下:&&& list(map(lambda x: str(x*x),range(10)))
['0', '1', '4', '9', '16', '25', '36', '49', '64', '81']
再看reduce的用法。reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
比方说对一个序列求和,就可以用reduce实现:&&& from functools import reduce
&&& reduce(lambda x,y:x+y,[1,2,3,4])
Python内建的filter()函数用于过滤序列。和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。例如返回一个list中的奇数:&&& list(filter(lambda x:x % 2 == 1,range(10)))
[1, 3, 5, 7, 9]
列表推导列表推导,又称列表生成式,即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。举个例子,要生成list [0,1, 2, 3, 4, 5, 6, 7, 8, 9]可以用list(range(10)):&&& list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
在python2中有点区别,python2中的range()直接生产列表而python3中生产的是一个range对象,需要通过list或者[]来生成。&&& [x for x in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
或者进阶一点点:&&& [x*x for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
&&& [str(x) for x in range(10)]
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
&&& L = ['Hello', 'World', 'IBM', 'Apple']
&&& [s.lower() for s in L]
['hello', 'world', 'ibm', 'apple']
感觉它的写法有点想lambda表达式。然后其中也可以多几层的嵌套:&&& [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
三层和三层以上的循环就很少用到了。yield和generator生成器简单地讲,yield 的作用就是把一个函数变成一个 generator。例如使用yield生成裴波那契数列:def fab(max):
n, a, b = 0, 0, 1
while n & max:
a, b = b, a + b
&&& for n in fab(5):
使用yield的好处在于,它返回的是一个generator生成器。类似于python3中的range()和python2中的xrange()。带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator,调用 fab(5) 不会执行 fab 函数,而是返回一个 iterable 对象!在 for 循环执行时,每次循环都会执行 fab 函数内部的代码,执行到 yield b 时,fab 函数就返回一个迭代值,下次迭代时,代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield。因为返回的是一个生成器,所以可以使用next()方法进行访问:&&& f = fab(5)
&&& next(f)
&&& next(f)
&&& next(f)
&&& next(f)
&&& next(f)
generator生成器,前面我们看了列表推导,使用[]进行生成,其中把[]换成(),就创建了一个generator:&&& L = [x * x for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
&&& g = (x * x for x in range(10))
&generator object &genexpr& at 0x7fd&
L是一个list,而g是一个generator。其中generator是可迭代的。装饰器装饰器(Decorator),当我们希望为函数增加功能,但是却不想修改原函数又或者没有权限修改原函数的时候,就需要用到装饰器了。比如我们有一个函数:def func():
print("I have a dream!")
I have a dream!
是的,我有一个梦想!现在我们想要知道我什么时候有一个梦想,就是我们需要在执行函数的时候打印时间。那么:'''定义一个装饰器'''
def log_time(func):
def wrapper(*args, **kw):
print("run %s() and time is :" % func.__name__+str(datetime.datetime.now()))
return func(*args,**kw)
return wrapper
def func():
print("I have a dream!")
输出:run func() and time is : 14:26:08.296495
I have a dream!
本质上,decorator就是一个返回函数的高阶函数。其中,我们给log_tim()传入一个参数,这个参数是一个函数对象,并且返回一个函数对象。然后在其中定义了wrapper(),这两个参数并没有意义,只是为了说明这里面可以传入任意类型的参数。然后用@语法将其放在函数定义处。其相当于:func = log_time(func)
由于log_time()是一个decorator,返回一个函数,所以,原来的func()函数仍然存在,只是现在同名的func变量指向了新的函数,于是调用func()将执行新函数,即在log_time()函数中返回的wrapper()函数。在使用装饰器时请注意:用decorator修饰一个函数得到另一个函数时,原来的那个函数依然是逻辑中心,而decorator所增加的只是相对外围的功能,不能那个什么宾那个什么主。即使去掉装饰器,整个函数的逻辑任然完整、清晰。
所谓优雅,都是yy出来的。好像和血统高贵的人的天生的优越感,是一回事。其实很多东西都是语法糖,小白看了都会甜蜜蜜,心欢喜。然而实际上光追求好看是没有用的,比如以前看到的,用python三行写快排def qsort(L):
if len(L) &= 1: return L
return qsort([lt for lt in L[1:] if lt & L[0]]) + [L[0]] + qsort([ge for ge in L[1:] if ge &= L[0]])
我以前觉得很厉害,现在明白了这种代码真没什么好的,除了会让你的队友发疯。世界上每天有那么多轮子发明,可是好用的轮子只需要一对。比如说函数式编程,其实大部分情况下列表推导已经足够用了。你非要用lambda表达式,不是自找麻烦么(一般只有面试官才会这么脑瘫去用这个方法)。你可以比较一下下面的square1和square2a = [1, 2, 3]
square1 = [x**2 for x in a]
square2 = map(lambda x: x**2, a)
(注:在python2下运行,python3里map返回的是迭代器)所以说还是要把基础的东西先搞懂,这个要实用的多比如说bytes、str、和unicode有什么区别比如说__init__
__slot__那些基本的方法都怎么用当然我不是反对优雅,只是要适度。在实用的基础上,去考虑优雅。
两本书 《Python cookbook》《编写高质量代码:改善Python程序的91个建议》差不多足矣。
from pymonad.List import *
from pymonad.Reader import curry
# Takes a simple number type and returns a 'List' containing that value and it's negative.
def positive_and_negative(x):
return List(x, -x)
# You can call 'positive_and_negative' normally.
positive_and_negative(9)
# returns List(9, -9)
# Or you can create a List...
x = List(9)
# ... and then use '&&' to apply positive_and_negative'
x && positive_and_negative
# also returns List(9, -9)
# But 'x' could also have more than one value...
x = List(1, 2)
x && positive_and_negative
# returns List(1, -1, 2, -2)
# And of course you can sequence partially applied functions.
def add_and_sub(x, y):
return List(y + x, y - x)
List(2) && positive_and_negative && add_and_sub(3)
# creates List(2)
# applies positive_and_negative: List(2, -2)
# then add_and_sub(3): List(5, -1, 1, -5)
# final result: List(5, -1, 1, -5)
写程序其实就跟写作文、遣词造句一样,会用成语会让你的文章显得老练,但是滥用成语就让人受不了了。程序也一样,重要的是要理解什么样的逻辑应当用什么样的语法来表达。其中关键的是让读代码的人是否容易理解,而不是执行起来是否正确。以下是一些个人的见解。总的来说原则是:在代码中提供恰到好处的信息量,既不缺少,也不冗余列表推导与循环什么时候列表推导作为代码来说比较清晰?当读者能够清晰理解你这条语句是要生成一个列表,除此以外什么都没有做的时候。比较: new_list = [v[1] for v in old_list if v[2]]
和new_list = []
for v in old_list:
new_list.append(v[1])
前者(对于熟练的程序员来说)明显更容易理解你的意图,即便不能一眼看清楚你所有的条件,他也能明白:这句语句只是将列表进行了一个格式的调整。再比较result = [v for v in iter(self.read_socket, '') if not v.startswith('+')]
和result = []
while True:
v = self.read_socket()
if v == '':
if not v.startswith('+'):
result.append(v)
前者明显就很糟糕,read_socket可能是个非常复杂、有明显副作用的过程,读代码的人不会期待你在这么短的语句当中完成个非常重要的逻辑。read_socket可能在里面抛出异常,你将没有机会给它加上try...except来进行处理,你也不会喜欢抛出的异常的堆栈信息里面有一堆&lambda& &genexpr&这样的意义不明的东西,而不是一个明确的行号。而且,很明显这是这段代码最重要的逻辑,这意味着这个逻辑以后可能会变更、会重构,你不会想要把一个列表推导变更得越来越复杂直到被迫推倒重来。另外,用到map和filter的都要尽量重写成列表推导。lambda表达式与具名函数Python是支持函数嵌套定义的,在已有的函数中可以嵌套定义新的函数:def my_func():
def subfunc():
嵌套的具名函数可以完全替代lambda表达式,而且有许多优点:一个函数名可以迅速告诉读代码的人这个函数在做什么抛出异常的时候,有函数名称明显要比显示为&lambda&强可以添加比较复杂的逻辑可以使用decorator具名函数可以用yield(也就是说可以定义嵌套的具名的generator,但不能定义lambda的generator)需要作为返回值的一部分的时候,在repr表达式当中能显示函数名,方便调试一般来说lambda表达式的使用一定要严格限定为(与关系):非常简单的逻辑,尤其最好不要在lambda当中再嵌套列表推演或者生成器表达式或者其他lambda表达式,非常不清晰没有副作用,或者只包装一个有副作用的表达式一次性使用(绝对不要用f = lambda x: ...这样的语句,虽然只有一行,但读代码的时候会很难找到f的定义)单返回值——使用tuple或者list的多返回值会让括号嵌套变得复杂难读懂。例如:return lambda x: lambda y: x + y
和def add_closure(x):
def add_func(y):
return x + y
return add_func
return add_closure
同样是嵌套的闭包,明显后一种写法要清晰得多,以后调试起来也要容易。可以在列表推导当中嵌套lambda,但最好不要在lambda当中嵌套列表推导。在列表推导中使用lambda的时候,首先确定这个逻辑是必要的;其次,给这个列表起一个非常明确的变量名,说明这个列表中的函数起什么作用;第三,给lambda表达式加上括号,让人能比较清楚地看到lambda表达式的开始和结束;最后,一定要警惕闭包封闭循环变量的方式,非常容易出意料之外的bug。multipliers = [(lambda x, i = i: x * i) for i in range(0, 20)]
修饰符/注解(decorator)修饰符是让代码变得优雅易读的非常重要的工具,正确运用能有非常多的好处。但也一定要注意:1. decorator中只做定义和初始化的工作,不要用decorator来执行某个操作。或者说,decorator不要有除了定义以外的副作用例如,严格杜绝下面的用法:def execute_once(f):
@execute_once
def my_func(param):
没有人会从代码中判断这个函数会在import的时候自动执行。而且,没有人会懂为什么my_func的值是None。2. 用decorator修饰一个函数得到另一个函数的时候,原函数的逻辑仍然是新函数的中心,而decorator增加的是相对无关紧要的或者外围的功能;尤其不要改变原函数的执行逻辑。严格杜绝下面的例子:def revert(f):
def newf(*args, **kwargs):
return not f(*args, **kwargs)
# No, please DON'T, really
return newf
def is_ok(my_str):
return my_str == 'OK'
3. 即使去掉修饰符,整个函数的逻辑仍然是完整、清晰、可读的。严格杜绝下面的例子:def repeat(f):
def newf(*args, **kwargs):
data, num = f(*args, **kwargs)
return [data] * num
return newf
def zeros(n):
return (0,n)
# What is it???
with语句with比起try...finally...来说,更强调“作用域”的概念。with接口一般有两种,一种是整个对象作为with表达式,一种是某个方法的返回值作为with表达式。应当遵循以下的规则:with的__enter__和__exit__过程中不应当执行过于复杂的操作。尤其应当避免在__exit__中抛出异常——在__exit__中抛出新的异常可能会覆盖旧的异常。with过程应当有明确的语义,一般来说代表某种生命周期(比如file,在with退出的时候会自动close),或者某种互斥过程(比如锁);如果要表达其他含义,最好用一个方法来返回一个with对象,方便读代码对于可能重入的过程(即:每次with是独立的,可以在多线程中同时进行多个),应当使用函数返回with对象的形式,这样实现起来不容易出bug能运用contextlib的情况下运用contextlib而不是手工实现__enter__和__exit__(不过这意味着要实现成函数返回with对象)with应当事先比较次要的逻辑。即使去掉with,with内的逻辑看上去仍然比较清晰、完整。能返回一个有意义的对象的时候,要返回一个有意义的对象,方便使用with ... as ...的语法比如,比起client = MyClient()
with client:
client.send(...)
应当用client = MyClient()
with client.transact() as trans_obj:
client.send(...)
self._logger.info('Transact %r succeeded.', trans_obj.id)
__getattr__, __getattribute__, property(descriptor), __setattr__,__delattr__Python可以以很多种方式重新定义对象属性的特性。应当注意:实施之前请再次思考是否真的必要。尤其是__setattr__和__getattribute__,它可能严重拖慢性能,因为每一个属性读写都会调用。优先使用propertyget过程不要修改对象的状态——增加cache之类的是可以的。考虑实现__dir__来让对象可以正确列出属性。如果重写了__getattr__和__setattr__,请至少考虑让下划线开头的属性遵循原始的规则,对于许多实现来说会提供一些便利。metaclass如果你是新手,尤其如果你不知道什么是metaclass,不要去强行用它。能使用其他方案比如decorator代替的要用decorator不要修改基类和类名总是从type派生出metaclass,你不会希望isinstance(myclass, type)返回False有清晰的文档说明这个metaclass的特性大概就这些吧。
首先,要会一些基本的python技巧,引用廖雪峰python教程:题主所提到的技巧,如[x*x for x in range(1, 11)]
斐波那契数列,如下def fib(max):
n, a, b = 0, 0, 1
while n & max:
a, b = b, a+b
写一个add函数,使得add(1)(2)的值为1+2,如下def add(a):
def tmp(b):
return a+b
return add
进一步,写一个add函数,使得add(1)(2)的值为1+2,add(1)(2)(3)的值为1+2+3,如下class add(int):
def __call__(self, a):
return add(self+a)
其次,要掌握python的代码风格,可参见的下的
这个是我在知乎看到最好的关于Python的问题了。题主想表达的应该是 idiomatic。我先提供3个链接,大家一定要看,一定要好好看,里面有很多Python惯用写法。好,我开始展示几个我认为非常优美的代码实现:循环列表, 直到找到符合的结果, 没有结果返回一个默认值通常这样:a = -1
for i in range(1, 10):
if not i % 4:
更好的写法:a = ''
a = next((i for i in range(1, 10) if not i % 4), -1)
执行调用直到某种情况通常这样:blocks = []
while True:
block = f.read(32)
if block == '':
blocks.append(block)
更好的写法:from functools import partial
blocks = []
for block in iter(partial(f.read, 32), ''):
blocks.append(block)
标记区分def find(seq, target):
found = False
for i, value in enumerate(seq):
if value == target:
found = True
if not found:
更好的写法:def find(seq, target):
for i, value in enumerate(seq):
if value == target:
threading.Locklock = threading.Lock()
lock.acquire()
print 'Critical section 1'
print 'Critical section 2'
lock.release()
其实是这样的:lock = threading.Lock()
with lock:
print 'Critical section 1'
print 'Critical section 2'
忽略抛出的异常try:
os.remove('somefile.tmp')
except OSError:
with ignored(OSError):
os.remove('somefile.tmp')
就算用python2, 我也强烈建议把这样的函数放在项目里@contextmanager
def ignored(*exceptions):
except exceptions:
如果你使用python3.4或以上可以使用标准库的 contextlib.suppressclass suppress:
def __init__(self, *exceptions):
self._exceptions = exceptions
def __enter__(self):
def __exit__(self, exctype, excinst, exctb):
return exctype is not None and issubclass(exctype, self._exceptions)
最简单的缓存通常这样实现缓存:def web_lookup(url, saved={}):
if url in saved:
return saved[url]
page = urllib.urlopen(url).read()
saved[url] = page
return page
可以这样写@cache
def web_lookup(url):
return urllib.urlopen(url).read()
def cache(func):
saved = {}
@wraps(func)
def newfunc(*args):
if args in saved:
return saved[args]
result = func(*args)
saved[args] = result
return result
return newfunc
werkzeug中的cached_property实现的也很好():class cached_property(property):
def __init__(self, func, name=None, doc=None):
self.__name__ = name or func.__name__
self.__module__ = func.__module__
self.__doc__ = doc or func.__doc__
self.func = func
def __set__(self, obj, value):
obj.__dict__[self.__name__] = value
def __get__(self, obj, type=None):
if obj is None:
return self
value = obj.__dict__.get(self.__name__, _missing)
if value is _missing:
value = self.func(obj)
obj.__dict__[self.__name__] = value
return value
工作中,有时候要构造一个复杂的、嵌套的字典,最痛苦的是你不知道会嵌套几级,怎么做呢?In : tree = lambda : defaultdict(tree)
In : t = tree()
In : t['a']['b'] = 1
In : t['c'] = 1
In : t['d']['e']['f'] = 10
In : print t
defaultdict(&function &lambda& at 0x7f6dd95c55f0&, {'a': defaultdict(&function &lambda& at 0x7f6dd95c55f0&, {'b': 1}), 'c': 1, 'd': defaultdict(&function &lambda& at 0x7f6dd95c55f0&, {'e': defaultdict(&function &lambda& at 0x7f6dd95c55f0&, {'f': 10})})})
更多的花样玩法可以看原贴 。由于本人太忙,没空复习算法和编译原理, 更没空继续撕逼。和
在写一个据说全网速度第一的数据库上面撕逼失败。想继续撕逼的可以直接去
找原作者撕,我非常认可原作者对「Call a function until a sentinel value」这种模式的用法。我对本回答下的内容负责,并且永不会改。如果对你有帮助,觉得对就点个赞,觉得我引用是错的,不好的可以点个反对。
不同人群写 Python的阶乘函数1 . 普通青年def f(n):
if n == 1:
return n * f(n - 1)
2 . 工程师def f(n):
return reduce(lambda x, y:x*y, range(1, n+1))
3 . 懒惰的人f = lambda n: n==1 or n * f(n-1)
所谓优雅,其实是由于这门语言的语法糖很甜,给(之前没有接触过的)人造成了一种“卧槽,好厉害”的错觉,其实很多情况下其他语言也可以,只不过可能实现起来不这么“优雅”而已。这里简单介绍一点Python“优雅”的代码和这颗糖的名字,至于这颗糖的更深层次的东西,这里一律略过。首先是lambda表达式。lambda表达式是一种非常简洁的定义函数的形式,不过一般不推荐写lambda表达式。比如求两个数的和,通过定义函数的写法为:def add(x, y):
return x + y
与之对应的lambda表达式为:add = lambda x, y: x + y
复杂的lambda表达式可以在一句话里面完成好多好多事情,比如我曾经将一位同事的140行代码的函数重构成了一句lambda表达式(通过反射)。然后是map/filter/reduce与列表推导,这三个函数和列表推导比较像,实现的功能也相似,不过一个通过函数的方式,另一个通过语法糖。举几个例子:map所做的事情是从一个集合到另一个集合的映射,比如有一个集合lst为[1,2,3,4,5,6,7,8,9],现在要求它的每一项的平方组成的新的集合:map(lambda item: item**2, lst)
而与其对应的列表推导式为:[item**2 for item in lst]
同理,filter也可以通过列表推导来实现,不过比起map/filter更加方便的是,列表推导可以更简单的将两者结合到一起,更重要的是,列表推导的效率更高。比如,还是有一个集合lst为[1,2,3,4,5,6,7,8,9],我们要求出所有奇数的平方的新的集合,通过列表推导的实现方式为:[item**2 for item in lst if item % 2]
而通过map/filter的实现为:map(lambda item: item ** 2, filter(lambda item: item % 2, lst))
另外一种很优雅的实现是装饰器。装饰器事实上就是一个函数到另一个函数的映射。你可以在不修改原函数代码的情况下为其增加新的功能。一个简单的例子,定义一个装饰器——timeit,用来实现在调用函数的时候,打印运行时间的功能。那么,你的代码看起来是这样的:@timeit
def func():
你不需要修改任何func的代码,即可实现在调用func的时候打印出运行时间,至于timeit的实现方式,可以参考这篇关于装饰器的简介:。还有一种很优雅的糖——with。学Python的人大多看到过书上一句话讲,使用open打开文件的时候,最好通过with语句来处理文件的关闭等,简而言之,应该是这样的:with open('/my/file/path', 'mode') as fp:
这样的调用可以自动处理资源释放等问题,可是为什么呢?事实上with语句是通过实现一个包括__enter__和__exit__的对象来实现的,你可以自己定义很多有意思的功能,比如,生成一个HTML标签,你可以这样做:with tag('div', class_='foo'):
print 'content of div'
&div class='foo'&
content of div
具体的实现,请参考官方文档:暂时写到这里吧,后面有时间再继续写一点。
a, b = b, a
读读 Python documentation 里的 The Python Language Reference 你就明白了,这都是很一般的写法。
从问题来看,题主python都还不熟,更别提优雅的代码实现了,还有楼上的回答,基本都是那几个函数式编程的工具,推荐《python cookbook》,楼上说的和题主问的都涵盖了,对着书敲一遍吧。
楼上都说了一些很好用、很实用的。补充一个 functools 包,里面的函数你用一次,就会彻底爱上。
看这个文档,爽溜溜的各种技巧generators,map,reduce,lambda ,decorators, *args等等各种优雅~
1. map、reduce、filter三兄弟和lambda匿名函数,拯救缓慢的for循环(然而其实也并没有特别快),伪装函数式语言(然而实际上还是OO),并且[哔]2. yield大法好,generator大法好。3. try else,for else,while else……4. monkey patch大法好,模块封装好了不想改模块本身但是又必须做修改?靠这个了……5. 装饰器大法好……6. 列表解析大法好……似乎能『优雅』的主要都在这几个点上,有空了我会补一点例子。然而任何一点用太多其实都会惹人厌,所以说PEP告诉你一行不要太长是有道理的……
已有帐号?
无法登录?
社交帐号登录

我要回帖

更多关于 python编程初学者指南 的文章

 

随机推荐