Python高级用法总结


Posted in Python onMay 26, 2018

列表推导(list comprehensions)

场景1:将一个三维列表中所有一维数据为a的元素合并,组成新的二维列表。

最简单的方法:新建列表,遍历原三维列表,判断一维数据是否为a,若为a,则将该元素append至新列表中。
缺点:代码太繁琐,对于Python而言,执行速度会变慢很多。

针对场景1,我们首先应该想到用列表解析式来解决处理,一行代码即可解决:

lista = [item for item in array if item[0] == 'a']

那么,何为列表解析式?

官方解释:列表解析式是Python内置的非常简单却强大的可以用来创建list的生成式。

强大具体如何体现?

可以看到,使用列表解析式的写法更加简短,除此之外,因为是Python内置的用法,底层使用C语言实现,相较于编写Python代码而言,运行速度更快。

场景2: 对于一个列表,既要遍历索引又要遍历元素。

这里可以使用Python内建函数enumerate,在循环中更好的获取获得索引。

array = ['I', 'love', 'Python']
for i, element in enumerate(array):
  array[i] = '%d: %s' % (i, seq[i])

可以使用列表推导式对其进行重构:

def getitem(index, element):
  return '%d: %s' % (index, element)

array = ['I', 'love', 'Python']
arrayIndex = [getitem(index, element) for index, element in enumerate(array)]

据说这种写法更加的Pythonic。

总结:如果要对现有的可迭代对象做一些处理,然后生成新的列表,使用列表推导式将是最便捷的方法。

迭代器和生成器

迭代器(Iterator)

这里的迭代可以指for循环,在Python中,对于像list,dict和文件等而言,都可以使用for循环,但是它们并不是迭代器,它们属于可迭代对象。

什么可迭代对象

最简单的解释:可以使用for...in...语句进行循环的对象,就是可迭代对象(Iterable),可以使用isinstance()方法进行判断。

from collections import Iterable 
type = isinstance('python', Iterable)
print type

什么是迭代器
迭代器指的是可以使用next()方法来回调的对象,可以对可迭代对象使用iter()方法,将其转换为迭代器。

temp = iter([1, 2, 3])
print type(temp)
print next(temp)

此时temp就是一个迭代器。所以说,迭代器基于两个方法:

  • next:返回下一个项目
  • iter 返回迭代器本身

可理解为可被next()函数调用并不断返回下一个值的对象就是迭代器,在定义一个装饰器时将需要同时定义这两个方法。

迭代器的优势

在构建迭代器时,不是将所有的元素一次性的加载,而是等调用next方法时返回元素,所以不需要考虑内存的问题。

迭代器应用场景

那么,具体在什么场景下可以使用迭代器呢?

  • 数列的数据规模巨大
  • 数列有规律,但是不能使用列表推导式描述。

生成器

生成器是一种高级迭代器,使得需要返回一系列元素的函数所需的代码更加的简单和高效(不像创建迭代器代码那般冗长)。

生成器函数

生成器函数基于yield指令,可以暂停一个函数并返回中间结果。当需要一个将返回一个序列或在循环中执行的函数时,就可以使用生成器,因为当这些元素被传递到另一个函数中进行后续处理时,一次返回一个元素可以有效的提升整体性能。
常见的应用场景是使用生成器的流数据缓冲区。

生成器表达式

生成式表达式是一种实现生成器的便捷方式,将列表推导式的中括号替换为圆括号。
和列表推导式的区别:列表生成式可以直接创建一个表,但是生成器表达式是一种边循环边计算,使得列表的元素可以在循环过程中一个个的推算出来,不需要创建完整的列表,从而节省了大量的空间。

g = (x * x for x in range(10))

总结:生成器是一种高级迭代器。生成器的优点是延迟计算,一次返回一个结果,这样非常适用于大数据量的计算。但是,使用生成器必须要注意的一点是:生成器只能遍历一次。

lambda表达式(匿名函数)

lambda表达式纯粹是为了编写简单函数而设计,起到了一个函数速写的作用,使得简单函数可以更加简洁的表示。

lambda和def的区别

lambda表达式可以省去定义函数的过程,让代码更加的简洁,适用于简单函数,编写处理更大业务的函数需要使用def定义。
lambda表达式常搭配map(), reduce(), filter()函数使用

  • map(): map函数接受两个参数,一个是函数,一个是序列,其中,函数可以接收一个或者多个参数。map将传入的函数依次作用于序列中的每个元素,将结果作为新的列表返回。
    #将一个列表中的数字转换为字符串 map(str, [1,2,3,4,5,6])

  • reduce():函数接收两个参数,一个是函数,另一个是序列,但是,函数必须接收两个参数reduce把结果继续和序列的下一个元素做累积计算,其效果就是reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)。

  • filter():该函数用于筛选,将传入的函数,依次作用于每个元素,然后根据函数的返回值是True还是False,决定是留下还是丢弃该元素。

装饰器

装饰器本质是一个Python函数,它可以让其它函数在没有任何代码变动的情况下增加额外功能。有了装饰器,我们可以抽离出大量和函数功能本身无关的雷同代码并继续重用。经常用于具有切面需求的场景:包括插入日志、性能测试、事务处理、缓存和权限校验等。

那么为什么要引入装饰器呢?

场景:计算一个函数的执行时间。

一种方法就是定义一个函数,用来专门计算函数的运行时间,然后运行时间计算完成之后再处理真正的业务代码,代码如下:

import time 

def get_time(func):
  startTime = time.time()
  func()
  endTime = time.time()
  processTime = (endTime - startTime) * 1000
  print "The function timing is %f ms" %processTime

def myfunc():
  print "start func"
  time.sleep(0.8)
  print "end func"

get_time(myfunc)
myfunc()

但是这段代码的逻辑破坏了原有的代码逻辑,就是对所有func函数的调用都需要使用get_time(func)来实现。
那么,有没有更好的展示方式呢?当然有,那就是装饰器。

编写简单装饰器

结合上述实例,编写装饰器:

def get_time(func):
  def wrapper():
    startTime = time.time()
    func()
    endTime = time.time()
    processTime = (endTime - startTime) * 1000
    print "The function timing is %f ms" %processTime
  return wrapper
  
print "myfunc is:", myfunc.__name__
myfunc = get_time(myfunc)
print "myfunc is: ", myfunc.__name__
myfunc()

这样,一个简单的完整的装饰器就实现了,可以看到,装饰器并没有影响函数的执行逻辑和调用。
在Python中,可以使用"@"语法糖来精简装饰器的代码,将上例更改为:

@ get_time
def myfunc():
  print "start func"
  time.sleep(0.8)
  print "end func"

print "myfunc is: ", myfunc.__name__
myfunc()

** 装饰器的调用顺序**
装饰器可以叠加使用,若多个装饰器同时装饰一个函数,那么装饰器的调用顺序和@语法糖的声明顺序相反,也就是:

@decorator1
@decorator2
def func():
  pass

等效于:

func = decorator1(decorator2(func()))

被装饰的函数带参数

上述实例中,myfunc()是没有参数的,那如果添加参数的话,装饰器该如何编写呢?

#被装饰的函数带参数
def get_time3(func):
  def wrapper(*args, **kwargs):
    startTime = time.time()
    func(*args, **kwargs)
    endTime = time.time()
    processTime = (endTime - startTime) * 1000
    print "The function timing is %f ms" %processTime
  return wrapper
@ get_time3
def myfunc2(a):
  print "start func"
  print a
  time.sleep(0.8)
  print "end func"

a = "test"
myfunc2(a)

带参数的装饰器

装饰器有很大的灵活性,它本身支持参数,例如在上述实例中,@get_time装饰器唯一的参数就是执行业务的函数,当然也可以在装饰器中添加参数,加以逻辑判断。

内置装饰器

Python中,常见的类装饰器包括:@staticmathod、@classmethod和@property

  • @staticmethod:类的静态方法,跟成员方法的区别是没有self参数,并且可以在类不进行实例化的情况下调用。
  • @classmethod:跟成员方法的区别是接收的第一个参数不是self,而是cls(当前类的具体类型)
  • @property:表示可以直接通过类实例直接访问的信息。

以上,是本次整理的Python高级用法,本文将持续更新。

Python 相关文章推荐
python如何在终端里面显示一张图片
Aug 17 Python
python实现外卖信息管理系统
Jan 11 Python
Python使用pip安装报错:is not a supported wheel on this platform的解决方法
Jan 23 Python
500行Python代码打造刷脸考勤系统
Jun 03 Python
Python的log日志功能及设置方法
Jul 11 Python
Flask配置Cors跨域的实现
Jul 12 Python
Django 简单实现分页与搜索功能的示例代码
Nov 07 Python
为什么黑客都用python(123个黑客必备的Python工具)
Jan 31 Python
pycharm设置python文件模板信息过程图解
Mar 10 Python
使用pygame编写Flappy bird小游戏
Mar 14 Python
python 实现两个线程交替执行
May 02 Python
MATLAB 如何求取离散点的曲率最大值
Apr 16 Python
关于Python的一些学习总结
May 25 #Python
windows下python和pip安装教程
May 25 #Python
python2.7实现爬虫网页数据
May 25 #Python
python sys.argv[]用法实例详解
May 25 #Python
python切片及sys.argv[]用法详解
May 25 #Python
windows下python安装pip图文教程
May 25 #Python
python3.6使用pymysql连接Mysql数据库
May 25 #Python
You might like
如何使用动态共享对象的模式来安装PHP
2006/10/09 PHP
理解和运用PHP中的多态性[译]
2011/08/02 PHP
php将session放入memcached的设置方法
2014/02/14 PHP
PHP编程中的__clone()方法使用详解
2015/11/27 PHP
jQuery 开天辟地入门篇一
2009/12/09 Javascript
JavaScript Event学习第七章 事件属性
2010/02/07 Javascript
js数组方法扩展实现数组统计函数
2014/04/09 Javascript
jquery中使用循环下拉菜单示例代码
2014/09/24 Javascript
jQuery Ajax调用WCF服务详细教程
2015/03/31 Javascript
JQuery跳出each循环的方法
2015/04/16 Javascript
jquery插件unobtrusive实现片段式加载
2015/06/15 Javascript
vue组件如何被其他项目引用
2017/04/13 Javascript
Angular 4依赖注入学习教程之Injectable装饰器(六)
2017/06/04 Javascript
[js高手之路]从原型链开始图解继承到组合继承的产生详解
2017/08/28 Javascript
Vue DevTools调试工具的使用
2017/12/05 Javascript
mockjs,json-server一起搭建前端通用的数据模拟框架教程
2017/12/18 Javascript
JavaScript实现与使用发布/订阅模式详解
2019/01/19 Javascript
细述Javascript的加法运算符的具体使用
2019/10/18 Javascript
vuejs实现下拉框菜单选择
2020/10/23 Javascript
python数据结构之图深度优先和广度优先实例详解
2015/07/08 Python
python黑魔法之编码转换
2016/01/25 Python
pygame实现俄罗斯方块游戏(AI篇1)
2019/10/29 Python
python中类与对象之间的关系详解
2020/12/16 Python
技术副厂长岗位职责
2013/12/26 职场文书
公司离职证明范本
2014/01/13 职场文书
临床医学专业求职信
2014/08/08 职场文书
2014年网络管理员工作总结
2014/12/01 职场文书
小学新教师个人总结
2015/02/05 职场文书
乱世佳人观后感
2015/06/08 职场文书
七年级思品教学反思
2016/02/20 职场文书
python实现三次密码验证的示例
2021/04/29 Python
深入理解python协程
2021/06/15 Python
一篇带你入门Java垃圾回收器
2021/06/16 Java/Android
厉害!这是Redis可视化工具最全的横向评测
2021/07/15 Redis
python对文档中元素删除,替换操作
2022/04/02 Python
使用 Koa + TS + ESLlint 搭建node服务器的过程详解
2022/05/30 NodeJs