python之函数作用域&装饰器

函数作用域

1.定义全局变量和局部变量并访问

count = 0
def f():
    count = 10
    print(count)
print(count)
f()
#结果:控制台输出
# 0     #这个是 全局变量 count
# 10    #这个是函数 f() 中的局部变量  count

2.对访问全局变量和局部变量的理解

#出错:
count = 0
def f():
    print(count)
    count = 10
f()
#local variable 'count' referenced before assignment
#赋值前引用的局部变量'count'
'''
原因(理解):程序在执行到 def f(): ,程序将该函数中的代码块先加载到内存中,在该函数被调用时,才开始执行代码
                而此时,内存中已经存在局部变量 count ,所以在 print(count)  代码中可以找到   count 局部变量
                而在执行  count = 10  代码之前, 执行print(count) ,所以会出现如下错误:
                            #local variable 'count' referenced before assignment
                            #赋值前引用的局部变量'count'
'''

3.在函数中对全局变量的修改(global关键字的使用)

global_argu = 10
def f():
    global global_argu
    global_argu =66666666
    print("f() :" + str(global_argu))
f() #先执行  f() 函数,作用是:修改 全局变量 global_argu = 66666666
print(global_argu)  #输出经过 f() 函数修改之后的全局变量global_argu = 66666666
# #结果
# # f() :66666666
# # 66666666

4.修改父函数的局部变量(nonlocal 关键字的使用)

def outer() :
    count = 10
    def inner():
        nonlocal count
        count = 20
        print("inner() count :" + str(count))#inner() count :20
    inner()
    print("outer() count:" + str(count)) #outer() count:20
    # 结果:count 的值都为 20
outer()
#结果
# inner() count :20
# outer() count:20
#结论:通过这种方式可以改变父函数中 count 变量的值

 

装饰器

装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。

强调装饰器的原则:

1 不修改被装饰对象的源代码

2 不修改被装饰对象的调用方式

装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能

 

无参装饰器

1.被修饰的函数无参

# import time
#
# def timer(func):
#     def wrapper():
#         start_time = time.time()
#         func()
#         end_time = time.time()
#         print('耗时:',end_time-start_time)
#     return wrapper
#
# def foo():
#     time.sleep(3)
#     print('foo function ...')
#
# foo = timer(foo)
# foo()


import time

def timer(func):
    def wrapper():
        start_time = time.time()
        func()
        end_time = time.time()
        print('耗时:',end_time-start_time)
    return wrapper
@timer # foo = timer(foo)
def foo():
    time.sleep(3)
    print('foo function ...')
foo()
'''
说明:
@timer  相当于
foo = timer(foo)
foo()
'''

 

2.被修饰的函数有参数

import time

def timer(func):
    def wrapper(*args,**kwargs):
        start_time = time.time()
        ret = func(*args,**kwargs)
        end_time = time.time()
        print('耗时:',end_time-start_time)
        return ret
    return wrapper
@timer
def max_f(a,b):
    time.sleep(2)
    if a>b:
        return a
    else:
        return b

print(max_f(6,8))
print(max_f(9,2))

有参装饰器

# 有参装饰器
def auth(auth_type):
    def auth2(func):
        def wrapper(*args,**kwargs):
            if auth_type == 'file':
                name = input('name:').strip()
                password = input('password:').strip()
                # 读取文件获取内容
                if name == 'puker' and password == '123':
                    print('auth successfull')
                    res = func(*args,**kwargs)
                    return res
                else:
                    print('fail auth')
            elif auth_type== 'mysql':
                print('从数据库中获取数据')
        return wrapper
    return auth2


@auth(auth_type='file')
def index():
    print('welcome to index page!')

index()

 

被多个装饰器修饰

# @aaa
# def func():
#     pass
#
#
# func=aaa(func)

# @ccc
# @bbb
# @aaa
# def func():
#     pass
#
# func=ccc(bbb(aaa(func)))


#
# @ccc('c')
# @bbb('b')
# @aaa('a')
# def func():
#     pass
#
# func=ccc('c')(bbb('b')(aaa('a')(func)))
执行流程

 

多个装饰器示例

import time

current_login = {'name':None,'login':False}

def timer(func):
    def wrapper(*args,**kwargs):
        start_time = time.time()
        res = func(*args,**kwargs)
        end_time = time.time()
        print("耗时:",end_time-start_time)
        return res
    return wrapper

def auth(auth_type):
    def auth2(func):
        def wrapper(*args,**kwargs):
            if current_login['name'] and current_login['login']:
                res = func(*args,**kwargs)
                return res
            if auth_type == 'file':
                name = input('name:').strip()
                password = input('password:').strip()
                if name == 'puker' and password == '123':
                    print('successfull auth')
                    res = func(*args,**kwargs)
                    current_login['name'] = name
                    current_login['login'] = True
                    return res
                else:
                    print('auth error')
            elif auth_type == 'mysql':
                print('从数据库中读取数据')
        return wrapper
    return auth2

@timer
@auth(auth_type='file')
def index():
    print('welcome to index page!')
@auth(auth_type='file')
def home():
    print('welcome to home page')


index()
home()
示例

 

 

 

高阶函数

高阶函数定义:
1.函数接收的参数是一个函数名

2.函数的返回值是一个函数名

3.满足上述条件任意一个,都可称之为高阶函数

 

一切不过是一个指针(变量),指向对应的内存区

 

闭包

只是对变量作用域的一种应用,在嵌套函数中,要拿到内嵌的函数,一定会通过外部的函数,而拿到内嵌的函数后,

该函数可以利用父函数

 

posted @ 2018-07-23 22:35  zwyk  阅读(92)  评论(0)    收藏  举报