博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python Tips阅读摘要
阅读量:6231 次
发布时间:2019-06-21

本文共 3006 字,大约阅读时间需要 10 分钟。

发现了一本关于Python精通知识点的好书《》,关于Python的进阶的技巧。摘录一些比较有价值的内容作为分享。

*args and **kwargs

在函数定义的时候我们经常看到*args和 **kwargs这两个定义对象。*args代表了函数定义中所有non-keyworded(这个词实在很难翻译)的传入参数,而**kwargs代表的所有带有keyworded的传入参数,举个栗子:

def test_var_args(*args, **kwargs):    print("args:{0}, kwargs:{1}".format(args,kwargs))test_var_args(1,2,3)>>>args:(1, 2, 3), kwargs:{}test_var_args(a=1,b=2,c=3)>>>args:(), kwargs:{'a': 1, 'c': 3, 'b': 2}

通过这个栗子我们可以清晰地区分keyworded和non-keyworded的区别了。本质上来说,args是一个数组,kwargs是一个字典。

args and *kwargs 最常用于装饰器,也可以用于monkey patching(猴子补丁),用来在运行时动态修改已有的代码,而不需要修改原始代码。

  • monkey patching
    monkey patch指的是在运行时动态替换,一般是在startup的时候.
    用过gevent就会知道,会在最开头的地方gevent.monkey.patch_all();把标准库中的thread/socket等给替换掉.这样我们在后面使用socket的时候可以跟平常一样使用,无需修改任何代码,但是它变成非阻塞的了.
    应用场景包括,一个已经定义好的函数被大量的引用,如果后面需要替换这个函数的话,直接在函数入口处进行替换即可。举个栗子,将ujson代替json:
main.pyimport json  import ujson  def monkey_patch_json():      json.__name__ = 'ujson'      json.dumps = ujson.dumps      json.loads = ujson.loads  monkey_patch_json()  print 'main.py',json.__name__  import sub  ======================sub.pyimport json  print 'sub.py',json.__name__

可以看到json在该模块中被完美替换,这个方法也可以用来做单元测试使用。

Generators生成器

首先区分Iterable、Iterator和Iteration三个概念:任何具有__iter__()或__getitem__()方法的对象,Python就认为它是一个iterable;使用内置的iter()函数来生成iterator,iterator可以通过__next__()方法来获取下一个元素。iterator遍历元素的过程可以认为iteration。

生成器同样是可迭代对象,但是你只能读取一次,因为它并没有把所有值存放内存中,它动态的生成值。
Yield是关键字, 用起来像return,yield在告诉程序,要求函数返回一个生成器,举个栗子:

def createGenerator():    my_list=range(3)    for  i in my_list:        yield i*igen= createGenerator() print(next(gen))print(next(gen))print(next(gen))print(next(gen)) #StopIteration

Map, Filter and Reduce

  • map
    Map的定义是将某函数处理所有输入参数,其定义为:

    map(function_to_apply, list_of_inputs)

例如:

items = [1, 2, 3, 4, 5]

squared = list(map(lambda x: x**2, items))
当时这两者还可以通过lambda表达式进行多个函数处理同一个输入的情况,这是一个非常美妙的转换,栗子如下:

def multiply(x):    return (x*x)def add(x):    return (x+x)funcs = [multiply, add]for i in range(5):    value = list(map(lambda x: x(i), funcs))    print(value)# Output:# [0, 0]# [1, 2]# [4, 4]# [9, 6]# [16, 8]

神奇的事情发生了,两个函数对于同一个输入参数都进行处理,并返回在了结果中。

  • filter

    filter(function_to_apply, list_of_inputs)

在大部分的情况下map和filter都可以通过list/dict/tuple Comprehensions来实现。

List Comprehensions语法:[expr for iter_var in iterable] 或 [expr for iter_var in iterable if cond_expr]
L = [expr for iter_var in iterable]:for iter_var in iterable的作用是依次取 iterable赋值给iter_var,而expr for iter_var in iterable的作用就是依次取值给iter_var,expr做运算后,继续循环,expr运算得到的值赋给变量L

map

map(function_to_apply, list_of_inputs)

通过函数对于结果进行处理,并返回聚集结果。例如:

from functools import reduceproduct = reduce((lambda x, y: x * y), [1, 2, 3, 4])# Output: 24

Collections

Collections包括几个常用的数据结构:

  • defaultdict : 是dict的子类,实现了dict的所有方法,功能使用上与dict.setdefault()类似,但是defaultdict构建时给出默认值。
  • orderdict:dict自排序。
  • counter:计数器,可以对iterator计数,也可以对list计数。
  • deque:队列。
  • nametuple:继承自tuple,我认为本质上是快速创建仅包括属性的类对象,从这个角度上看非常实用。
  • enum:枚举类型,但是必须注意,枚举成员本身类型就是枚举类型,因此如果需要将枚举成员用以读写及比较操作将会报错。
    这篇教程中还讲了一些协程coroutine、异步IO的概念,但都属于技巧性的内容,讲的不透彻就不再一一分享。

转载于:https://www.cnblogs.com/kendrick/p/7483261.html

你可能感兴趣的文章
mysql创建唯一索引
查看>>
Vijos1935不可思议的清晨题解
查看>>
Android Studio修改默认Activity继承AppCompatActivity
查看>>
Servlet和Android网络交互基础(3)
查看>>
javascript:void(0) 含义
查看>>
<<、|=、&的小例子
查看>>
愿Linux红帽旋风吹得更加猛烈吧!
查看>>
Secret Code
查看>>
Vue动态组件
查看>>
ES2017异步函数现已正式可用
查看>>
DBA-io
查看>>
【转】批处理常用符号详解
查看>>
Uncaught TypeError: jQuery.i18n.browserLang is not a function
查看>>
JavaScript中的闭包详解
查看>>
【JSP】JSP Action动作标签
查看>>
iOS:CoreText的常用语法
查看>>
dropify,不错的图片上传预览插件
查看>>
为什么都不写博
查看>>
希腊字母表
查看>>
httpd配置文件httpd.conf规则说明和一些基本指令
查看>>