欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python-函数进阶

程序员文章站 2024-03-17 16:08:58
...

一、名称空间:存放变量名与对应值绑定关系的地方。

分为三种:locals(),是函数内的名称空间,包含局部变量与形参;globals():全局变量,函数定义所在模块的名字空间;builtins():内置模块的名字空间。

level = 'l0'
n = 22
def func():
    level = 'l1'
    n = 33
    print(locals())

    def outer():
        n = 44
        level = 'l2'
        print(locals(),n)

        def inner():
            level = 'l3'
            print(locals(),n)
        inner()
    outer()
func()

#打印 func()/outer()/inner()

{'level': 'l1', 'n': 33}
{'level': 'l2', 'n': 44} 44
{'level': 'l3', 'n': 44} 44

#名称空间查找顺序:局部名称空间--->全局名称空间--->内置名称空间

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

作用域即范围:全局范围:全局存活,全局有效;局部范围:临时存活,局部有效。

#1、作用域即范围
        - 全局范围(内置名称空间与全局名称空间属于该范围):全局存活,全局有效
      - 局部范围(局部名称空间属于该范围):临时存活,局部有效
#2、作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关,如下
x=1
def f1():
    def f2():
        print(x)
    return f2
x=100
def f3(func):
    x=2
    func()
x=10000
f3(f1())

#3、查看作用域:globals(),locals()


LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
locals 是函数内的名字空间,包括局部变量和形参
enclosing 外部嵌套函数的名字空间(闭包中常见)
globals 全局变量,函数定义所在模块的名字空间
builtins 内置模块的名字空间

 

二、闭包

定义:内部函数包含对外部作用域,而非全局作用域的引用。之前我们都是通过参数将值传给函数,闭包给我们提供了一种新的方式。

 outer():
    name='alex'

    def inner():
        print("在inner里面打印外层函数的变量", name)
    return inner

f = outer()
f()

 闭包的意义:

返回的函数对象,不仅仅是一个函数对象,在该函数外层还包裹着一层作用域,这使得函数无论在何处调用,都优先使用自己外层包裹的作用域。应用:延迟计算。

def counter():
    n = 0

    def incr():
        nonlocal n
        x = n
        n += 1
        return x

    return incr


c = counter()
print(c())
print(c())
print(c())
print(c.__closure__[0].cell_contents)  # 查看闭包的元

 三、装饰器

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

强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方法。

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

开放封闭原则:对修改封闭,对拓展开放

装饰器就是闭包的一种应用场景

 

装饰器的使用:

1、无参数的使用

 

import time
def timmer(func):
    def wrapper(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print('run time is %s' %(stop_time-start_time))
        return res
    return wrapper

@timmer
def foo():
    time.sleep(3)
    print('from foo')
foo()

 

 

 

 

2、有参数的使用

def auth(driver='file'):
    def auth2(func):
        def wrapper(*args,**kwargs):
            name=input("user: ")
            pwd=input("pwd: ")

            if driver == 'file':
                if name == 'egon' and pwd == '123':
                    print('login successful')
                    res=func(*args,**kwargs)
                    return res
            elif driver == 'ldap':
                print('ldap')
        return wrapper
    return auth2

@auth(driver='file')
def foo(name):
    print(name)

foo('egon')