Python高级用法总结

  • 格式:pdf
  • 大小:152.49 KB
  • 文档页数:3

Python⾼级⽤法总结

Python很棒,它有很多⾼级⽤法值得细细思索,学习使⽤。本⽂将根据⽇常使⽤,总结介绍Python的⼀组⾼级特性,包括:列表

推导式、迭代器和⽣成器、装饰器。

列表推导(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⾼级⽤法,本⽂将持续更新。