zoukankan      html  css  js  c++  java
  • python 函数(二)

    一 函数的嵌套

    def func(*args,**kwargs):
        def func_inner(a,b,c):
            print(a,b,c)
        func_inner(*args,**kwargs)
    func(1,2,c=3)
    

      

      针对函数的嵌套,外层函数定义阶段,内层函数调用阶段,*args,**kwargs这样写以后,外层函数调用时,只需要和内层函数定义阶段相匹配就ok了。

    二 三元表达式

      pass

    三名称空间(namespace)与作用域

      名称空间:

        名称空间的分类

        名称空间的加载顺序

        名称空间的生命周期

        名称空间 谁可以使用谁

      作用域

        三种名称空间的作用域

        作用范围

    四 闭包

      定义:  

        调用外层函数,返回内层函数的地址,这个内层函数是带着外层函数的环境变量返回的。

    def foo():
        name='egon'
        def bar():
            print(name)
        return bar
    b=foo()
    name='alex'
    b()
    

      输出:

    egon            foo就是闭包函数,不管在任何位置调用,都自带对外界作用域的引用。
    

      

      函数名.__closure__

        如果不是闭包函数,返回None

        如果是闭包函数,返回作为闭包函数调用外层环境的变量地址。以元组的形式返回,每个元素都是一个地址。

    五 关键字

      locals() :返回当前作用域的局部变量。

    Return a dictionary containing the current scope's local variables.
    

      nonlocal :,对外层的变量有用,但不是全局变量。否则,报错。

    a=100
    def func1():
        def func2():
            nonlocal a
            print(a)
    func1()
    

      报错信息:

    SyntaxError: no binding for nonlocal 'a' found
    

      global

    六 函数的本质

      一等公民

      函数名

      egon语录:函数的作用域关系跟定义位置有关,跟调用位置无关。

    money=100
    def foo():
        print('money:',money)
    
    def bar():
        money=1000
        foo()
    bar()
    

      输出:  

    money: 100                  #foo()函数定义在全局。尽管是在bar函数局部名称空间内被调用,但money的作用域还是要去全局中找。
    

      

      在上述例子的基础上的拓展

    money=100
    def foo():
        print('money:',money)
    money=10
    def bar():
        money=1000
        foo()
    bar()
    

      输出:

    money: 10                                  #money:10 ,这跟函数的从上到下的加载顺序有关,但引用的money是全局变量还是不变的。
    

      

      

    七 带参数的装饰器

      装饰器的外层右加了一层装饰器。

    def wrapper(func):
        def bar(*args):
            print('======')
            res=func(*args)
            return res
        return bar
    @wrapper
    def plus(x,y):
        return x+y
    
    res=plus(2,2)
    print(res)                            #这是最基本的装饰器
    

      

      带参数的装饰器。想要传参数,将参数写在现成的装饰器的外面,在装饰器的外面在套一层函数。最内层被装饰的函数可以调用到外层的所有参数,可以根据第二层的装饰器的参数,来决定第一层装饰器是否执行。

    def auth(tag):
        def wrapper(func):
            def bar(*args):
                if tag:
                    print('======')
                res=func(*args)
                return res
            return bar
        return wrapper
    @auth(0)
    def plus(x,y):
        return x+y
    
    @auth(1)
    def multi(x,y):
        return x*y
    
    res=plus(2,2)
    print(res)
    print('---------------------------------')
    res=multi(2,3)
    print(res)
    

      

      

      egon讲的另一个例子。调用函数时自动将函数地址保存到一个字典中,key值是传的参数,value值是函数内存地址。

    func_dict={}
    
    def auth(key):
        def deco(func):
            func_dict[key]=func
        return deco
    
    
    
    
    @auth('foo')                    #@auth('foo)=@wrapper       foo=wrapper(foo)
    def foo():
        print('foo')
    @auth('bar')
    def bar():
        print('bar')

      讲解时的思路是:   因为要传参,所以是 三层装饰器。先定义了auth(key),放一个参数进去。 deco(func),还是正常放函数。   func_dict[key]=func,走到这一步,要实现的功能已经实现了,没必要在写wrapper函数了。

      思路非常清晰。

      这样实现的效果是 auth传入的参数名随意改,对应的函数实际不会变,达到了隐藏函数的效果。最后直接 func_dict['foo']()就可以运行。

    八 装饰器的一个应用 @wraps

      Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变),为了不影响,Python的functools包中提供了一个叫wraps的decorator来消除这样的副作用。写一个decorator的时候,最好在实现之前加上functools的wrap,它能保留原有函数的名称和docstring。

      

    from functools import wraps
    
    def wrapper(func):
        def inner(*args,**kwargs):
            return func(*args,**kwargs)
        return inner
    
    def foo():
        '''
        foo函数
        :return:
        '''
        x=1
        return x
    print(foo.__name__,foo.__doc__)
    print('*'*50)
    @wrapper
    def foo():
        '''
        foo函数
        :return:
        '''
        x=1
        return x
    print(foo.__name__,foo.__doc__)
    print('*'*50)
    def wrapper(func):
        @wraps(func)
        def inner(*args,**kwargs):
            return func(*args,**kwargs)
        return inner
    
    @wrapper
    def foo():
        '''
        foo函数
        :return:
        '''
        x=1
        return x
    print(foo.__name__,foo.__doc__)

      输出:

    foo 
        foo函数
        :return:
        
    **************************************************
    inner None
    **************************************************
    foo 
        foo函数
        :return:
  • 相关阅读:
    GridSearchCV.grid_scores_和mean_validation_score报错
    scikit-learn使用fetch_mldata无法下载MNIST数据集的问题
    Python数据科学手册Seaborn马拉松可视化里时分秒转化为秒数的问题
    Jupyter导出PDF从入门到绝望(已解决)
    食谱数据库数据找不到的问题
    TensorBoard计算加速
    TensorBoard可视化
    TensorFlow高层封装:从入门到喷这本书
    <!DOCTYPE html> 详解
    不同数据库之间表数据的迁移
  • 原文地址:https://www.cnblogs.com/654321cc/p/7448715.html
Copyright © 2011-2022 走看看