末学者笔记--Python函数二玄

Python函数:二玄

一.名称空间和作用域                                                             

1.内置名称空间:

python启动时就有)python解释器内置的名字,print,max,min

Print其实是python内置的函数。

1. 全局名称空间:

(执行python文件时启动)定投定义的变量,如在Python界面直接定义的变量:a = 3 ,即为全局变量。

 

2. 局部名称空间:

(调用函数时启动,调用结束失效)函数内部定义的变量

如:

在函数内的定义的一个变量即为局部变量。

 

总结

三者的加载顺序

        内置--->全局--->局部

    

        三者的访问顺序

        局部--->全局--->内置

 

二.装饰器                                                                         

1.什么是装饰器?

在不修改源代码和调用方式的基础上给函数增加新的功能,即为装饰器,多个装饰器可以装饰在同一个函数上

 

2.无参装饰器

 

def add(he):
    def wrpper():
        he()  #he=message
        print('这是一个笑话')

    return wrpper
@add     #@add达到的效果:message=add(message)=wrpper 这是其id内存地址
def message():

    print('有2棵树就有4只鸟')
message()

》》

2棵树就有4只鸟

这是一个笑话

》》

 

3.有参装饰器:

def add(he):
    def wrpper(x,y):
        he(x,y)  #he=message
        print('这是一个笑话')

    return wrpper
@add   #message=add(message)=wrpper 这是其id内存地址
def message(x,y):

    print('有%s棵树就有%s只鸟' % (x,y))
message(2,4)

》》

2棵树就有4只鸟

这是一个笑话

》》

4.带参数的装饰器:

 

def default_engine(engine=None):
    def auth(func):
        def deco(*args, **kwargs):
            user = input('user:')
            password = input('password:')
            if engine == 'mysql':
                if user == 'root' and password == 'root':
                    res = func(*args, **kwargs)
                    return res
                else:
                    print('用户名或密码错误')
            else:
                print('没有这个引擎')
        return deco
    return auth

@default_engine(engine='mysql')
def index():
    print('welcome to home page')
# res = default_engine(engine='mysql')
# index = res(index)
index()

三.迭代器                                                                    

1.什么是迭代器?

   迭代是一个重复的过程,即每一次重复为一次迭代,并且每次迭代的结果都是下一次迭代的初始值

while True:    #只是单纯的重复,因此不是迭代

    print('===>')

 

l = [1,2,3]

count = 0

while  count<len(l):   #首先是重复动作,其次上一次的结果是下一次的初始值,因此,是迭代

    print(l[count])

    count+=1

 

2.为什么要有迭代器?可迭代对象迭代器对象

(1)为何要有迭代器?

对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器

 

2什么是可迭代对象?

可迭代对象指的是内置有__iter__方法的对象,即obj.__iter__,如下:

'world'.__iter__

(4,5,6).__iter__

[1,2,3].__iter__

{'a':1}.__iter__

{'a','b'}.__iter__

open('a.txt').__iter__

 

3什么是迭代器对象?

可迭代对象执行obj.__iter__()得到的结果就是迭代器对象

而迭代器对象指的是即内置有__iter__又内置有__next__方法的对象

 

4文件类型是迭代器对象

open('a.txt').__iter__()

open('a.txt').__next__()

 

5总结:

迭代器对象一定是可迭代对象,而可迭代对象不一定是迭代器对象

 

四:生成器                                                               

1.什么是生成器?

只要函数里有yield关键字,那么函数名()得到的结果就是生成器,并且不会执行函数内部代码

# 生成器就是迭代器

 

2.returnyield区别:

    # return只能返回一个值

# yield可以返回多个值,同一时间只能存储一个值;缺点:没有索引,不能后退取值

 

return的方式
def test():
    l = []
    for i in range(10):
        l.append(i)
    return l
print(test()[4])

 

Yield方式:

def test():
    l = ['a','b','c']
    for i in l:
        yield i
for i in test():
    print(i)

》》

a

b

c

》》

 

【特殊】:

def test():
    l = ['a','b','c']
    for i in l:
        yield i
print(next(test()))
print(next(test()))
print(next(test()))


print('==============')


a = test()  #生成器的算法是:每次直接调用如‘print(next(test()))’,都会刷新迭代数位,即从新取值;赋予给一个变量即可免去算法刷新
print(next(a))

print(next(a))
print(next(a))

》》

a

a

a

==============

a

b

c

》》

 

五:匿名函数                                                                           

1. 定义

匿名函数的定义:lambda,自带return

匿名函数通常只调用一次,之后不再使用。

 

2. 格式:

lambda x,y: x+y     

其整体是一个函数内存地址,即(lambda x,y: x+y)(ab)为调用函数

直接输出:

print((lambda x,y:x+y)(1,2))

》》

3

》》

3.lambda的使用场景

#max  sorted  map  filter  zip】

info = {
    'li':2000,
    'zhao':35000,
    'wu': 34000,
    'du': 40000
}

1# max:取最大值

print(max(info,key=lambda k:info[k]))   #max 本身做了一个循环比较;

》》

du

》》

解释:max本身开始循环info字典的key值,将key值赋予给匿名函数的参数‘k’,匿名函数代入‘k’值后返回info字典的对应value值,此时max再进行大小比较,取出最大value值,但输出的是其对应的key值。

 

2# sorted:排序

print(sorted(info,key=lambda k:info[k]))
print(sorted(info,key=lambda k:info[k],reverse=True))   #反向排序

》》

['li', 'wu', 'zhao', 'du']

['du', 'zhao', 'wu', 'li']

》》

原理:同max的原理,

 

3# map:映射

names = ['zhao','wu','du']

#想在每个元素后面加一个‘nb’,通常如下:
l1 = []
for name in names:
    res = '%s_nb' % name
    l1.append(res)
print(l1)

》》

['zhao_nb', 'wu_nb', 'du_nb']

》》

 

但使用匿名函数更简单:

print(list(map(lambda name:'%s_nb' % name,names)))

结果一样,同理map映射也是变成迭代器对象

res = map(lambda name:'%s_nb' % name,names)
print(res.__next__())
print(res.__next__())
print(res.__next__())

》》

zhao_nb

wu_nb

du_nb

》》

 

4# filter:过滤

names = ['zhao_nb', 'wu_nb', 'du_nb','li']
print(list(filter(lambda i: i.endswith('nb'),names)))
print(list(filter(lambda i: not i.endswith('nb'),names)))

》》

['zhao_nb', 'wu_nb', 'du_nb']

['li']

》》

 

【补】 # zip:拉链

l1 = [1,2,3,4]
l2 = ['a','b','c']
print(list(zip(l1,l2)))
res = zip(l1,l2)    #很明显zip后是个迭代器对象
print(next(res))
print(next(res))
print(next(res))

》》

[(1, 'a'), (2, 'b'), (3, 'c')]

(1, 'a')

(2, 'b')

(3, 'c')

》》

将列表对应元素连成一个元组,元素个数不对应则去除多余元素。

=======================================分割线===================================

原文地址:https://www.cnblogs.com/feige2L/p/11023231.html