博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python 函数(二)
阅读量:4348 次
发布时间:2019-06-07

本文共 3549 字,大约阅读时间需要 11 分钟。

一 函数的嵌套

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 barb=foo()name='alex'b()

  输出:

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

  

  函数名.__closure__

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

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

 

五 关键字

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

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

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

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

  报错信息:

SyntaxError: no binding for nonlocal 'a' found

  global

六 函数的本质

  一等公民

  函数名

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

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

  输出:  

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

  

 

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

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

  输出:

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

  

  

七 带参数的装饰器

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

def wrapper(func):    def bar(*args):        print('======')        res=func(*args)        return res    return bar@wrapperdef plus(x,y):    return x+yres=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*yres=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 wrapsdef wrapper(func):    def inner(*args,**kwargs):        return func(*args,**kwargs)    return innerdef foo():    '''    foo函数    :return:    '''    x=1    return xprint(foo.__name__,foo.__doc__)print('*'*50)@wrapperdef foo():    '''    foo函数    :return:    '''    x=1    return xprint(foo.__name__,foo.__doc__)print('*'*50)def wrapper(func):    @wraps(func)    def inner(*args,**kwargs):        return func(*args,**kwargs)    return inner@wrapperdef foo():    '''    foo函数    :return:    '''    x=1    return xprint(foo.__name__,foo.__doc__)

  输出:

foo     foo函数    :return:    **************************************************inner None**************************************************foo     foo函数    :return:

 

转载于:https://www.cnblogs.com/654321cc/p/7448715.html

你可能感兴趣的文章
c++可变参数(示例)
查看>>
oracle数据库常用命令
查看>>
4923: [Lydsy1706月赛]K小值查询 平衡树 非旋转Treap
查看>>
MySQL 配置文件详解
查看>>
maven 中央仓库地址
查看>>
实现页面查看xml或json数据类似控制台效果
查看>>
Kali配置教程
查看>>
Leetcode: Combination Sum IV && Summary: The Key to Solve DP
查看>>
获取动态类型变量的属性值
查看>>
C++冒泡排序
查看>>
js 数组操作
查看>>
OAuth : open Authorization 开发授权
查看>>
vue2
查看>>
数据处理程序
查看>>
mysql创建索引/删除索引操作
查看>>
第522篇--DataTable to Excel C#
查看>>
C++\virtual 虚函数、纯虚函数
查看>>
asp.net mvc 4多级area实现技巧
查看>>
Solr
查看>>
MySQL binlog数据库同步技术总结
查看>>