python自学哪本书比较好,python自学好找工作吗

亲爱的读者们,今天我们来聊聊,python自学哪本书比较好 python自学好找工作吗,让我们开始吧!

大家好,给大家分享一下电脑课python装b专用代码,很多人还不知道这一点python源码库。下面详细解释一下。现在让我们来看看!

1. 三目操作符

学过C语言的同学,或者看过《C语言从入门到放弃》这本书的同学一定不会对“三目操作符”这种画面感十足的操作符感到陌生。

然而,直到我完成python小学一年级课程的时候才发现原来python也有类似的东西python自学可能吗。比如:

deffoo(val):

if val == 42:

return "you are a programmer!"

else:

return "you are a manong!"

或者你也可以这样写:

deffoo(val):

return "you are a programmer!" if val == 42 else "you are a manong!"

友情提示:此特技要小心使用。否则容易暴露你大师的本质。不要像撸主当年,把所有的if/else都改成神都看不懂的 "do xxx if xx else xxx"句式。

2. 会叫的都是鸭子

讲道理的话,这个应该是一个坑,而非装逼技巧。由于撸主当年是从C++党转学python的,刚开始写代码总喜欢这样:

if isinstance('c', CPlusPlus):

assert(isinstance('python', CPlusPlus)

更变态的时候甚至这样:

assert(type('C++') == CPlusPlus)

聪明的你可能会问撸主:“type和isinstance有什么区别啊?”。可你想不到的是撸主会回答你:“自己google去“,然后留给你一个傲娇的背影。

等等!撸主你说这玩意跟“鸭子”有什么关系。事实是酱紫的,有一天撸主正在琢磨“开电脑用左手开机好,还是右手开机好,还是双手齐上好”这个宇宙终极问题时,一位高年级的大哥哥过来告诉我:“没必要这样,没必要到处assert isinstance 这种。因为python是鸭子类型。会叫的都是鸭子。”

然后撸主问他“你会叫吗?”

友谊的小船说翻就翻……

“什么?你不知道鸭子类型?不会自己google吗?”

3. 内建函数和lamda

比如如下一个简单的例子:我需要将一个字符串列表中所有满足包含“result"字段的字符串筛选出来。

低年级的同学可能会这么做:

deffoo(xxx):

result_list = list()

for ele in org_list:

if "result" in ele:

result_list.append(ele)

BUT,这样做“一点都不酷!”。要酷还得靠装逼:

result_list = filter(lambda ele : "result" in ele, org_list)

不信的话,你就去试试咯:

map(lambda ele : ele + 1, (1, 2, 3, 4))

reduce(lambda x,y:x+y, range(3))

4. iterator和generator

这俩哥们看着很像、读着也很像。

其实不难区分,generator返回不用return,而用yield;所以你凡是看到yield的地方,很可能就是generator这装逼犯。

iterator呢,就是实现了next()方法和__iter__,__iter__方法返回它自己。而当你调用next()方法时,会返回一个值。通常,这个next值会由generator产生。

换种说法,你也可以这样理解,generator是用来生成iterator的。

闲话少说,举个栗子。

如果高年级的同学问你:小学生?怎么保证埃希不空大?你一定要回答他,最简单的generator是这样的:

generator=(i for i in xrange(0, 3))

纳尼?yield呢?哦,你要yield啊,那就这样写:

defgenerator():

for i in range(3):

yield i

你看,我顺便又介绍了一道幼儿园考题:range和xrange的区别。

那么iterator呢?都说了generator就是用来生成iterator的啦。

() // 第一个

generator().next() // 第二个

上面只是一个简单的示例,这段简单的代码在实际的工作中并没有什么卵用。

那么它应用的场景有吗?下一次返回的结果依赖于上一次返回的结果。因为yield的作用是每次函数调用执行到这里就停止了,下次调用从yield后面的语句开始。

比如说树的遍历之类的。

5. bind

bind这种东西简直是为撸主这种懒人量身定制的,想想啊:你写一个好多好多参数的函数,没事你bind一个参数,又变成了函数A,你再换种姿势bind,又变成了函数B。

用过C++ boost库,或者对C++1x有所了解的童鞋可能知道我说的是什么了。如果没了解过,请参考上面一段话自行脑补。

其他的小节撸主介绍的都是些python内置函数,或者'__'开头的内置方法等。这个小节撸主准备介绍一条裤。

你可能会问:撸主撸主,裤跟bind有什么关系?别急嘛,骚年。这个库是functools,里面有好几个函数都棒棒哒哦。不过这里撸主只准备介绍跟bind相似的partial方法。

看看它的用法,是不是跟bind很像?

defadd(a, b):

return a + b

plus2 = functools(add, 2)

plus3 = functools(add, 3)

....

6. 修饰器

1) decorator

有时候撸代码撸累了,想发发微信,找个人帮忙撸代码。你可以试试这样:@xxx 帮我打个日志。XXX就帮你打日志了。

deflog(func):

defwrap(*arg, **kargs):

start = ()

func(*arg, **kargs)

end = ()

print " time = %.6f sec" % (end - start)

return wrap

然后你想要打日志,又懒得撸代码了,就这样:

@log

deffoo(arg):

# do something

以下是干货,容易着火。

修饰器的本质就是对函数做些修饰,然后返回一个函数(callable object)。也就是所谓的高阶函数。

因此上面的式子不用语法糖直白的写出来就是:

foo = log(foo)

看到没,foo其实就是一个log返回的callable object wrap的别名。

举个栗子,如果需要这样的修饰器,我们应该怎么写呢?

@decro(1, 2)

deffoo(*args, **kargs):

pass

先翻译一下,先把(1,2)传给decro,然后把foo传给decro;然后你返回给我一个能接受(*args,**kargs)参数的函数:

foo = decro(1,2)(foo)

一定要记住,foo是一个callable object。事情就变得很简单了:

defdecro(*args, **kargs): # 1,2

defwrap(func): # foo

def_(*args, **kargs): # foo 也必须是一个callable

func(*args, **kargs)

return _

return wrap

哪里不会点哪里,就是这么简单。装逼技能Decorator GET!

2) wraps

到这里就结束了?如果到这里就结束了,高年级的同学知道了一定又会回来鄙视我们:你试试打印下foo函数,看看是什么?你试着打印一下:

>>> foo

天啦噜!不是foo么,怎么变成"_"了?

别急,这个时候你需要前一节提到的那条裤了:functools,然后对你的decorator做一点小小的改动:

from functools import wraps

def decro(*args, **kargs):

defwrap(func):

#看这里看这里

@wraps(func)

def_(*args, **kargs):

func(*args, **kargs)

return _

return wrap

然后foo就变成了:

>>> foo

沿着修饰器继续深挖,你可以挖出所谓的函数式编程、闭包一大堆看起来很高大上的概念。可是由于撸主水平有限,只好劳烦您自行google啦。

7. deor

至于描述器,多的不多说了。直接看看使用前后效果对比图:

1)缘起

当时情况是这样的,撸主正在看clang python binding的代码,看到这么一段:

classCachedProperty(object):

def__init__(self, wrapped):

self.wrapped = wrapped

try:

self.__doc__ = wrapped.__doc__

except:

pass

def__get__(self, instance, type=None):

if instance is None:

return self

value = self.wrapped(instance)

setattr(instance, self.wrapped.__name__, value)

return value

当时我的心情是这样的:

2)内置方法

有点流弊啊!虽然我看不懂,但是警察叔叔早就告诉过我“外事不决问google“啊。

1. python有三个内置函数,__set__、__get__、__delete__;

2. 只定义__get__方法,非数据描述器(non-data deor);

3. 定义了__delete__ 或者 __set__ 方法的叫做数据描述器(data deor);

“虽然不知道上面的话在说什么,但是感觉好厉害的样子”。嗯,不明白没关系,不明白才好装X嘛。按照python的尿性,凡是装X的技巧都离不开python的内置方法,也就是'__'开头、'__'结尾的方法。由于__delete__不常用,俺们只要记住__get__和__set__这个东西好了。

3)__dict__

咱么先从字典说起。看下面一个例子:

classTest(object): pass

Test.a = 'a'

Test.b = 'b'

t = Test()

t.c = 'c'

t.b = 'tb'

setattr(t, 'setkey', 'val')

print Test.__dict__

print t.__dict__

print t.a

print t.c

print t.b

print t.setkey

output是:

{'a': 'b', '__module__': '__main__', 'b': 'b', '__dict__': , '__weakref__': , '__doc__': None} #这是Test.__dict__

{'c': 'c', 'b' : 'tb', 'setkey' : 'val'} #这是t.__dict__

a #t.a

c #t.c

tb # t.b

val # t.setkey

这个例子说明几点:

1. 对象和类都有个字典:__dict__

2. 在对象中查找不到的属性,会从类中查找 (t.a)

3. 对象中属性的优先级高于类中的优先级 (t.b)

4. 设置属性(set)的时候,会在对应的dict里增加元素 (Test.a =xxx, t.b = xxx)

5. setattr 跟 '=' 操作符,操作对象的属性时,看起来作用是一样的。

通常的情况下,属性查找如此简单:先找对象的__dict__,然后再找类的__dict__;都找不到就抛异常;

4)属性查找

当加入所谓的deor的时,事情变得稍微复杂了一点点。对于一个对象的属性,新的顺序是:

1. python自动属性 (python自动生成的属性,比如__doc__等)

2. 在类(及其祖先类)的__dict__中查找data deor,如果存在,返回data deor中__get__方法调用的结果

3. 在对象的__dict__中查找

4. 在类(及其祖先类)的__dict__中查找non-data deor,存在则返回对应__get__调用的结果

5. 在类(及其祖先类)的__dict__中查找普通属性

这样,在原来的属性查找顺序上,我们加上了non-data deor和data deor,分别插在2、4的位置上。

5)回到deor

A:“你说的这么多,跟deor有什么关系?“

B: "对啊,对啊,一点都没教会我装逼!"

别急,骚年。

回到1)中的例子,然后再看看2)中的定义,有木有发现,这其实就是一个deor。这个CacheProperty有什么作用呢? 看下面一个使用场景(这个栗子也来自clang python binding):

classConfig:

...

@CachedProperty

deflib(self):

lib = self.get_cindex_library()

register_functions(lib, not Config.compatibility_check)

Config.loaded = True

return lib

Config定了一个lib方法,这个方法做一些相对耗时的操作才能获得我们想要的lib对象。比如说加载配置文件:有没有办法可以做到只在第一次调用的时候加载配置文件,其他的时候都从缓存里读呢?

看CacheProperty 的实现:

1 首先它是一个non-data deor;

2. 第一次的时候,按照4)所述的查找顺序,

2.1 由于Config和其对象的__dict__中没有lib,它会走到第4步;

2.2 然后开始执行__get__方法,该方法调用lib方法,计算出lib的值value=self.wrapped(instance) (这个wrap方法在CacheProperty __init__方法中被设置self.wrapped = wrapped, 此时wrapped就是lib方法);

2.3 随后调用setattr方法,将计算到的值set到对象的__dict__中

3. 之后调用的时候,由于对象的__dict__中已经有这个key了。直接返回对应的值就可以了。

这只是个non-data deor的例子,它验证了属性查找中non-data deor顺序的正确性。

对于data deor属性查找,可以参看下面一个例子:

classDataDesc(object):

def__init__(self, obj):

print 'obj', obj

= obj

def__set__(self, obj, val):

print 'set called', obj, val

.__name__ = val

def__get__(self, obj, type=None):

print '__get__', obj, type

classTest(object):

@DataDesc

deffoo(self):

print 'foo'

deffunc(self):

print 'func'

t = Test()

print t

t.foo = 'c'

t.__dict__['foo'] = 'c'

print t.__dict__

print t.foo

当然,这里还有几个细节没有介绍: setattr, getattr 甚至于__getattribute__, __getattr__。当你弄明白了所谓的描述器,这些东西都很简单啦!随随便便google一大堆。

8. 深度魔法--metaclass

说实话,一开始让我介绍metaclass,我是拒绝的。因为装逼,有的时候还是要站在巨人的肩膀上。

喏,链接在此,拿走不谢。

纳尼,你还问我要中文翻译版?

9. 一本书

如果你只学到第8点,可能高年级的同学。还会挑战你:你那么腻害,你知道GIL么?

你可能会问:什么是GIL?然后高年级的同学肯定会鄙视你:你连GIL都不知道,肯定没看过源码吧。

你知道我只是介绍装逼特技,so,指望我这种水平去写个python源码剖析出来是不现实的。不过我可以推shu啊

据说下雨天,看书跟看源码更配哦。

看完此书,你的装逼领域又可以扩展到C了哦。还可以学会一点怎么让C也面向对象,告别汪星人了。

自此,妈妈再也不用担心学C的找不到对象啦!

由于水平有限,文章缪误之处,请不吝指出!多谢!

本期败家讲坛到此结束,请留意下期公告:


原文地址1:https://blog.csdn.net/Night368/article/details/135367407
python手册 http://www.78tp.com/python/

  • 28
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值