Python--函数对象&闭包函数

Posted mr-chenshuai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python--函数对象&闭包函数相关的知识,希望对你有一定的参考价值。

函数对象:

  • 函数是第一类对象

第一类对象:

  • 指可以在执行期创造并作为参数传递给其他函数或存入一个变量的实体     

第一类对象所特有的特性为:

  • 可以当容器被存入变量或其他结构
  • 可以被作为参数传递给其他函数
  • 可以被作为函数的返回值
  • 可以在执行期创造,而无需完全在设计期全部写出
  • 即使没有被系结至某一名称,也可以存在

函数、类、模块等所有对象都是第一类的

 


闭包函数:

  • 内部函数

    函数内定义的函数为内部函数

  • 闭包函数

    内部函数包含对外部作用域而非全局作用域的引用

 

定义闭包函数的基本形:

def 外部函数名():
    内部函数需要的变量
    def 内部函数():
        引用外部变量
    return 内部函数


----------------------------------------------------------

# 举例

def f1():
    x=1
    def f2():
        print(x)
    return f2
f = f1()
print(f)        # <function f1.<locals>.f2 at 0x00000189C2226158>
f()
print(f.c.__closure__[0].cell_contents)  # 查看闭包元素   闭包函数都有 __closure__ 方法
# 这里内部函数f2打印x,f2中没有变量x,去上一层找,找到f1中的x,然后打印,这里的 f 就是闭包函数,包含了对f1中x的引用

  


 

闭包特点

  • 返回的函数对象,不仅仅是一个函数对象,该函数外还包裹了一层作用域,这使得该函数无论在何处调用,优先使用自己外层包裹的作用域,也就是说永远携带着一种状态
  • 拿到函数的内存地址后,想什么时候用就什么时候用,一种惰性计算

 


 

闭包函数和作用域:

money = 666
def foo(name):
    print(‘%s have %s money‘ %(name,money))
 
def foo1():
    money = 999
    foo(‘shuai‘)
foo1()                                    #  shuai have 666 money
 
# 这里打印不会是999,函数在定义时就已经确定了作用域,所以当doo函数内没有money时,会去找全局的money

 

闭包函数让我始终有着一笔钱

money = 888
def func1():
    name = ‘shuai‘
    def func():
        money = 666
        def foo():
            print(‘%s have %s money‘ %(name,money))
        return foo
    return func
f = func1()
f1 = f()
 
def foo1():
    money = 999
    f1()
foo1()
 
# 包了两层
    # 先看func1和func,这两个函数返回闭包函数 func,包含了 name
    # func 和 foo ,这俩函数返回闭包函数 foo,包含了 money
# f = func1()   拿到 func,再执行f1 = f() 拿到 foo

  


 

简单应用:

from urllib.request import urlopen
def get(url):
    return urlopen(url).read()
print(get(‘http://www.xiaohua100.cn‘))
 
# 获取校花网信息 
# 问题:每次都要传url,网站过多,url是没法记住的
 
 
# 闭包应用
from urllib.request import urlopen
def index(url):
    def get():
        return urlopen(url).read()
    return get
 
xiaohua = index(‘http://xiaohua100.cn‘)
print(xiaohua())
jidong = index(‘https://www.jd.com/‘)
print((jidong()))
 
# 这样想要下载哪个就执行哪个,不用就放着,并且不用传url;

  

 

以上是关于Python--函数对象&闭包函数的主要内容,如果未能解决你的问题,请参考以下文章

python 闭包装饰器

Python之闭包装饰器

python闲谈--闭包

scala编程——函数和闭包

Python深入04 闭包

理解Python中的闭包