Python入门教程[6]-高级特性

  • A+
所属分类:python快速入门
摘要这一篇文章会讲python的一些高级特性,这些特性会对编程的简洁性有所提高。我个人是很喜欢使用列表解析的。

切片

切片用于获取一个序列(列表或元组)或者字符串的一部份,返回一个新的序列或者字符串,使用方法是中括号中指定一个列表的开始下标与结束下标,用冒号隔开,切片在之前讲解字符串的时候有介绍过,不只是字符串,列表或元组使用切片也非常常见。

list = ['0','1','2','3','4','5']
list[1:3]
>> ['1','2']
list[2:] #省略end截取到最后
>> ['2','3','4','5']
list[:2] #省略start默认为0
>> ['0','1']

列表解析

这个方法我个人觉得是很好的,给生成list提供了一种很便利的方法。我们可以直接看下面的例子。

list = ['0','1','2','3','4','5']
['0'+i for i in list] #这个是给每个字符串前面加上0
>> ['00', '01', '02', '03', '04', '05']

lambda匿名函数

匿名函数就是有的时候我们不想要给这个函数一个明确的函数名,就可以这么使用。我们看一下下面的例子,匿名函数和map与filter合在一起的使用方法。

list = [1,2,3,4,5]
f = filter(lambda x: x%2==0,list) #返回符合条件的元素,类似于mathematica中的select
m = map(lambda x:x*x,list) #对列表list每个元素进行平方操作
for i in f:
    print(i)
>> 2,4
for i in m:
    print(i)
>> 1,4,9,16,25

生成器

生成器是一个迭代器,不同的是,生成器只能被迭代一次,因为每次迭代的元素不是像列表元素一样,已经在内存中,而是你每迭代一次,它生成一个元素。

g = (x**x for x in range(1,3))
for x in g:
    print(x)
>> 1,4
for x in g:
    print(x)
>> #没有输出,再次运行生成器是不会有输出的

使用生成器有什么好处呢?因为生成器不是把所有元素存在内存,而是动态生成的,所以当你要迭代的对象有非常多的元素时,使用生成器能为你节约很多内存,这是一个内存友好的特性。

yield

yield 的使用方法和return类似。不同的是return可以返回有效的Python对象,而yield返回的是一个生成器,函数碰到return就直接返回了,使用了yield的函数,到yield返回一个元素,当再次迭代生成器时,会从yield后面继续执行,直到遇到下一个yield或者函数结束退出。

下面我们看一斐波那契数列的例子:

def fib(n):
    count = 0
    a,b = 1,1
    while count<n:
        yield a
        a,b = b,a+b
        count = count+1

f = fib(10)
for i in f:
    print(i)
>> 1,1,2,3,5,8,13,21,34,55

装饰器

装饰器可以为函数添加额外的功能而不影响函数的主体功能。在 Python 中,函数是第一等公民,也就是说,函数可以做为参数传递给另外一个函数,一个函数可以将另一函数作为返回值,这就是装饰器实现的基础。装饰器本质上是一个函数,它接受一个函数作为参数。

我们下面看一个简单的例子

def decorate_learn(func): #这里的参数是原函数
    def decorate(*args,**kwargs): #这里的参数是原函数的所有参数
        print('这是一个装饰器')
        return func(*args,**kwargs) #返回函数的值
    return decorate

@decorate_learn
def add(x,y):
    return x+y

add(1,2)
>> 这是一个装饰器
   3

在上面的例子中,*arg,**kwargspython中函数的可变参数*args表示任何多个无名参数,是一个元组,**kwargs表示关键字参数,是一个字典。这两个组合表示了函数的所有参数。如果同时使用时*args参数列要在**kwargs前。

总之就是记住,这两个组合表示了函数的所有参数。

所以,上面的等价与下面的写法:

def decorate_learn(func): #这里的参数是原函数
    def decorate(*args,**kwargs): #这里的参数是原函数的所有参数
        print('这是一个装饰器')
        return func(*args,**kwargs) #返回函数的值
    return decorate

def add(x,y):
    return x+y

add = decorate_learn(add)
add(1,2)

而但是这样其实是有一个问题的,就是使用decorate_learn(add)这个后,就不是原来的函数add

add.__name__
>> decorate #这里可以思考一下为什么

在python中提供了一个方法来解决这个问题

from functools import wraps
def decorate_learn(func): #这里的参数是原函数
    @wraps(func)
    def decorate(*args,**kwargs): #这里的参数是原函数的所有参数
        print('这是一个装饰器')
        return func(*args,**kwargs) #返回函数的值
    return decorate

@decorate_learn
def add(x,y):
    return x+y

#add = decorate_learn(add)
add(1,2)
>> 3
add.__name__
>> add
  • 微信公众号
  • 关注微信公众号
  • weinxin
  • QQ群
  • 我们的QQ群号
  • weinxin
王 茂南

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: