函数进阶

命名空间

若变量x = 1,1存放于内存中,x也存放于内存中,名称空间存放x与1绑定关系的地方。

  • locals( ):是函数内的名称空间,包括局部变量和形参
  • globals( ):全局变量,函数定义所在模块的名字空间
  • __ builtins __:内置模块的名称空间

不同变量的作用域不同就是由这个变量所在的命名空间决定的。

作用域即范围

  • 全局范围:全局存活,全局有效
  • 局部范围:临时存活,局部有效

作用域的查找顺序

n = 10
def func():
    n = 20
    print('func:',n)
    def func1():
        n = 30
        print('func1:',n)
        def func2():
            print('func2:',n)
        func2()
    func1()
func()
func: 20
func1: 30
func2: 30

查找顺序:LEGB

  • L:locals
  • E:enclosing 外部嵌套函数的命名空间
  • G:globals
  • B:buintins

闭包

def func():
    n = 10
    def func1():
        print('func1:',10)
    return func1

f = func()
print(f)
f()
<function func.<locals>.func1 at 0x005B9B28>
func1: 10

装饰器

flag = False

def login(func):
    print(func)
    def inner(*args):
        global flag
        _acc = 'q1ang'
        _pwd = '123'
        if flag == False:
            print('未登录')
            acc = input('Account:').strip()
            pwd = input('Password:').strip()
            if acc == _acc and pwd == _pwd:
                flag = True
            else:
                print('账号/密码错误!')
        else:
            print('已登录')
        if flag:
            func(*args) #henan()
    return inner

@login
def henan(t):
    print('this is henan',t)
@login
def ningxia():
    print('this is ningxia')

# henan = login(henan) #inner

henan('nihao')
ningxia()

生成器

a = list(range(10))
b = (i+1 for i in a)  
print(b)  # <generator object <genexpr> at 0x0031FE40>
next(b)  
# 1 → 2 → 3 → ... → 10 → Traceback (most recent call last): 
# File "<stdin>", line 1, in <module>
# StopIteration
for i in b:  # 自动跳出循环
    print(b)

生成器的调用

a = list(range(10))
b = (i+1 for i in a)  
list(b)  # [1,2,3,4,5,6,7,8,9,10]

列表生成器

a = list(range(10))
b = [i+1 for i in a]  # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

斐波那契数列

def fib(m):
    n, a, b = 0, 0 ,1
    while n < m:
        yield b  # 函数执行过程冻结在这一步,并且把b的值返回给外面的next()
        a, b = b, a + b
        n = n + 1
    return 'done'
f = fib(15)  # 未执行,只生成了生成器
next(f)

for i in f:
    print(i)

send( )

  • 唤醒并继续执行
  • 发送一个信息到生成器内
def range1(n):
    count = 0
    while count < n:
        print('count',count)
        count += 1
        sign = yield count
        print('sign',sign)
n = range1(10)
n1 = next(n)
n.send('stop')
'''
count 0
sign stop
count 1
'''

迭代器

可以直接用于 for 循环的对象统称为可迭代对象:Iterable

  • 集合数据类型 list、tuple、dict、set、str
  • generator 生成器,可以被 next( ) 调用并不断返回下一个值的对象称为迭代器:Iterator
from collections import Iterable
print(isinstance('abc',Iterable))  # True

from collections import Iterator
print(isinstance((i for i in range(10)),Iterator))  # True

print(isinstance(iter([1,2,3,4,5]),Iterator))  # True  iter() 可以将可迭代对象转换为迭代器
posted @ 2018-08-01 23:33  q1ang  阅读(182)  评论(0编辑  收藏  举报