Python进阶教程(一)
概述
hi,朋友们大家好,今天将英文原著作者 @yasoob《Intermediate Python》进行翻译和在工作中使用的Python技巧进行了总结。Gitbook里面有翻译的版本,大家可以下载下来看看。我今天主要是将该英文原著翻译成适合自己的理解的语言,并附加一些自己在工作中使用Python的技巧。废话少说,下面我们依次来学习一下@yasoob的原著。
Intermediate Python 中译
如果在翻译过程中有问题或者code无法运行,还请各位大侠指正。
*args和**kwargs
我们在函数定义时,会经常使用*args和**kwargs这两个魔法变量,特别是函数参数数量不确定或参数较多时。当然*args和**kwargs这两个name并不是惟一的name,可以改成*as和**kwas,只要在命名前面加上修饰符*和**即可。我们先来看一下*args。
*args
def test_args_kwargs(name,*args):
print("frist arg: ",name)
for arg in args:
print("another arg through *argv: ",arg)
test_args_kwargs("brian","eric","rose")
#输出为
frist arg: brian
another arg through *argv: eric
another arg through *argv: rose
我们也可以通过参数列表进行传递,比如:
names=("brian","eric","rose")
test_args_kwargs(*names)
frist arg: brian
another arg through *argv: eric
another arg through *argv: rose
**kwargs
将不定长度的键值对作为参数传递给函数,我们来看一下。
def greet_me(**args):
for key,value in args.items():
print("{0}=={1}".format(key,value))
greet_me(name="brian",age=20,sex="男")
#输出为
name==brian
age==20
sex==男
或者也可以这样
person = {"name":"brian","age":20,"sex":"男"}
greet_me(**person)
#输出为
name==brian
age==20
sex==男
如何使用
在很多场景里面都大量使用比如: 1.装饰器 2.函数定义 3.单元测试 4.猴子补丁(在运行时修改某些代码),在英文版本里面主要介绍了通过猴子补丁修改API来进行测试。 ……
import someclass
def get_info(self,*args):
return "Test Data"
someclass.get_info=get_info
Debugging
我们在生产和测试环境很少安装IDE进行调试的,如有有紧急需要修改或者出现问题如何快速排查问题和定位问题是非常重要的意见事情,也是主要衡量一个工程师水平的一个标准。那么在Python是如何做呢? 1.日志,不仅在关键的业务处理进行相应的日志输出,也要在入口和出口进行详细的日志处理。 2.Debugging,我们可以通过pdb、ipdb和jupyter进行有效的调试。 3.python docstring一定规范写好,方便调试和定位问题,特别是研发人员的流失比较严重时。 ……
我们今天来看一下通过pdb通过命令行和嵌套debug代码这两种方式都可以调试代码。我们来看一下, 1.命令行运行
python -m pdb test.py
2.嵌套代码
import pdb
def method(*args,**kwargv):
pdb.set_trace()
...
method(name="sasa")
当函数调用时进入debug模式。 无论是命令行模式还是嵌套代码模式所有调试代码的命令都是一样的,主要有如下几个快捷键:
- c:继续在当前程序上下文执行直到遇到断点或者trace位置为止,即继续执行。
- w:显示当前执行程序上下文信息。
- a:打印当前函数的参数列表。
- s:执行当前代码行。
- n:执行下一行的代码。
Generators
Generators(生成器)很多教程在讲解Generators都会先讲解Iter(迭代器),因为生成器大多数场景都是基于迭代器的。所以我们先来了解学习一些迭代器相关的内容。
- Iterable(可迭代对象):Python即对象,呵呵。Python的任意对象定了返回__iter__方法或者支持下标的__getitem__方法,它就是一个可迭代的对象。可迭代对象就是提供迭代器的任何对象。
- Iterator(迭代器):一般是指定义了__next__方法的对象。
- Iteration(迭代):字面意思,不言而喻。实在不理解的,可以简单的理解为循环。
Generators也是一种迭代器,只不过你只能对其只能迭代一次,它并不是列表这种集合类型的数据保存在内存中,而是保存的是运行时的某个值。主要是通过yield来终止并暂存运行时栈,相当于保护现场进而为下次迭代提供记录和便利。特别一次性不需要全部结果集时显得非常重要。 我们来看一个简单的例子:
def fibon(n):
a=b=1
for i in range(n):
yield a
a,b=b,a+b
for i in fibon(3):
print(i)
#输出为
1
1
2
#通过next方法来进行获取生成器的下一个迭代
gen_fibon = fibon(3)
print(next(gen_fibon))
print(next(gen_fibon))
print(next(gen_fibon))
#输出结果为
1
1
2
#如果我们再进行下一个迭代时,会出现Exception,这说明我们的迭代已经完成,生成器已经没有再生成Python对象。
print(next(gen_fibon))
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-18-5f779bae9fed> in <module>()
----> 1 next(gen_fibon)
StopIteration:
我们来看一下python的string类型是不是可以直接通过迭代器来获取元素。比如:
name="brian"
next(name)
#输出结果为,告诉我们python的str了O型不是一个迭代器,那么就无法进行迭代。所以我们需要将str对象模型变成可迭代的python对象数据模型,只需要通过iter(object)方法即可。
TypeError: 'str' object is not an iterator
#代码修改
iter_name = iter(name)
next(iter_name)
iter(object)是将一个可迭代的对象变为一个迭代器对象,从而通过next来获取数据。
map,filter and reduce
map,filter,reduce这三个函数式python的buildin函数,是一个开箱即用的函数,更是Python提供面向函数编程的一个优势。我们先来看一下这三个函数的原型:
- map(function_apply,array/list_inputs)
- filter(function_apply,array/list_inputs)
- reduce(function_apply,array/list_inputs)
map
map在处理并行计算提供了极大的便利,巧妙的使用map可以使自己的application变得快速和代码优化。我们先看一个简单的例子:
temp=[2,7,14,18]
list(map(lambda x: x**2,temp))
#输出结果为:
[4, 49, 196, 324]
lambda 函数式python的匿名函数,处理逻辑简单开箱即用的“一行函数”。,当然我们也可以将输入统一,具体行为或者业务不一致的code分装成函数,将具体执行各自的任务和逻辑单元。比如:
def add(x):
return x+x
def multiply(x):
return x*x
funcs=(add,multiply)
for i in range(5):
print(list(map(lambda func:func(i),funcs)))
#输出为
[0, 0]
[2, 1]
[4, 4]
[6, 9]
[8, 16]
filter
filter这是一个过滤的build-in函数,它的作用主要在于过滤行为。
nums=range(-5,5)
less_than_zero=list(filter(lambda x:x<0,nums))
#输出为
[-5, -4, -3, -2, -1]
在后面的我们会介绍列表推导式也很方便,我可以改一下该例子。
list(i for i in nums if i<0)
#输出结果为同样的
reduce
reduce是将列表结果进行规约处理的,又叫“规约函数”.我们来看一下处理:
from functools import reduce
print(reduce(lambda x,y:x+y,(2,3,4,5)))
##输出为
14
set data struct
python中的set数据结构是等价于数学意义上的集合。数学意义上的集合最重要的性质有:唯一性,可重复性,无序性。那么在Python的set数据结构中数据元素也是表现如此。我们来看一个得到重复元素的例子。
str_nums=('a','a','b','c','c','c','d','e','f')
duplicates=set([x for x in str_nums if str_nums.count(x)>1])
print(duplicates)
{'a', 'c'}
当然你也可以使用collection的Counter去处理
from collections import Counter
print(Counter(str_nums))
##输出为
Counter({'a': 2, 'b': 1, 'c': 3, 'd': 1, 'e': 1, 'f': 1})
和set相关的操作自然想到交集、并集合差集。下面我们依次看一下Python提供的API。
colors=set({'red','yellow','green'})
input_colors=set({'red','blue'})
#交集API
print(input_colors.intersection(colors))
#输出
{'red'}
#差集API
print(input_colors.difference(colors))
#输出
{'blue'}
#并集API
print(input_colors.union(colors))
#输出
{'blue', 'green', 'red', 'yellow'}
值得注意的是set的定义是通过{}来定义的或者通过set()初始化来定义。
三元运算符
三元运算符和其它语言的三元运算符所表达的语义是相同的,只是形式不一样。我们来看下: condition_true if condition else condition_is_false
flag = True
print("Brian" if flag else "Not Brian")
#输出
Brian
总结
由于内容较多,所以分成三个博客篇幅来介绍。
- 微信小程序自定义数据分析试水
- 挂载银行前置机Ukey到windows server2012虚拟机的操作记录
- 文件上传速度查询方法
- “AS3.0高级动画编程”学习:第三章等角投影(上)
- su: 无法设置用户ID: 资源暂时不可用
- NumPY学习笔记
- LVS负载均衡下session共享的实现方式-持久化连接
- Centos6.9下RabbitMQ集群部署记录
- “AS3.0高级动画编程”学习:第三章等角投影(下)
- zabbix监控主机cpu达到80%后报警
- ssh登陆服务器locale告警的处理方法
- as3.0中如何阻止事件冒泡?
- Nginx+upstream针对后端服务器容错的运维笔记
- MongoDB日常运维操作命令小结
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- ReentrantLock可重入锁 Krains 2020-08-27
- Java中的线程 Krains 2020-08-24
- CAS Krains 2020-08-25
- 96. 不同的二叉搜索树 II Krains 2020-09-03 树
- 410. 分割数组的最大值 Krains 2020-08-29 20:21:39 动态规划二分查找
- 字典树 Krains 2020-09-01
- redis学习(十)
- vue修改浏览器的标题title
- 天天基金网数据接口
- Centos7实现开机自启EasySwoole
- input内文字与光标的初始位置调整
- 小程序push、unshift、concat
- mac下导出chrome插件及安装
- Job 资源对象
- ReplicaSet && DaemonSet 资源对象