Python闭包的详细介绍

Mar 26, 2017 pm 06:02 PM

在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。

我更倾向于后一种,把闭包看做一种组织代码的结构,原因我后面解释。

那闭包代码结构是怎样的呢?

Python中,一切皆对象,这当然包括函数了。函数对象可以赋值给一个变量,而且通过这个变量可以调用该函数;函数对象也作为参数进行传递,也可以作为某个函数的返回结果。而且,Python中,函数可以嵌套定义。

Python以函数对象为基础,为闭包这一语法结构提供支持

先看一个例子

def f1():
    name1 = 'Alice'
    name2 = 'Bob'
    def f2():
        print('hello,%s,%s' %(name1,name2))    return f2 


if __name__ == '__main__':
    name1 = 'David'
    name2 = 'Frank'
    func = f1()
    func()
    print(func.__closure__)
    print(func.__closure__[0].cell_contents)
    print(func.__closure__[1].cell_contents)# 输出hello,Alice,Bob
(<cell at 0x03A55CF0: str object at 0x03CBEA20>, <cell at 0x03CBEAD0: str object at 0x03CBEAA0>)
Alice
Bob
Salin selepas log masuk

函数 f2 定义在函数 f1 的内部,并且调用了 f1 内定义的变量name1 和 name2 。

f1 返回了 f2 这个函数对象,而实际上返回的 f2 中已经包括了 f1 中的变量name1 和name2,这一点从代码的运行结果中就可以看出来。

在主程序中,虽然重新定义了name1 和name2,但函数 func 执行时调用的仍然是定义时的变量值,即它的引用环境变量,而不是使用时的变量值。

总结一下,Python中,闭包就是一个包含了函数和引用环境变量的代码块,我倾向于把闭包看做一种代码结构,而不是函数,是因为第一次调用它的时候,只是把闭包的引用环境和内部的函数包装在一起,以一个函数对象来返回,而没有执行内部的函数,当调用这个函数对象时,才会执行内部的函数功能。

引用环境变量的值被保存在函数对象的closure属性中。closure里包含了一个元组(tuple)。这个元组中的每个元素是cell类型的对象。我们看到第一个cell包含的就是Alice,也就是我们创建闭包时的环境变量name1的取值。这一点从上面代码的运行结果中可以看出来。

现在回头看一看,百科对闭包的解释。

现在,再举一个例子:

# 此例子转自伯乐在线def line_def(a, b):
    def line(x):
        return a * x + b    return lineif __name__ == &#39;__main__&#39;:
    func = line_def(2, 3)
    print(func(5))# 输出13
Salin selepas log masuk

在这个例子中,函数line和环境变量 a, b 构成了闭包,我们只需改变a, b 的值就能获得不同的直线函数 line,提高了封装性,使得我们只需关注参数a, b就可以了,不要关心内部直线的实现。

闭包的最大特点是可以将外部函数的变量与内部函数绑定,并返回绑定变量后的函数(也即闭包),此时即便生成闭包的环境(外部函数)已经释放,闭包仍然存在。

闭包的一大应用就是装饰器,只不过其传递的是函数。这个下次再写。

Atas ialah kandungan terperinci Python闭包的详细介绍. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bagaimana untuk menyelesaikan masalah kebenaran yang dihadapi semasa melihat versi Python di Terminal Linux? Bagaimana untuk menyelesaikan masalah kebenaran yang dihadapi semasa melihat versi Python di Terminal Linux? Apr 01, 2025 pm 05:09 PM

Penyelesaian kepada Isu Kebenaran Semasa Melihat Versi Python di Terminal Linux Apabila anda cuba melihat versi Python di Terminal Linux, masukkan Python ...

Bagaimana Mengajar Asas Pengaturcaraan Pemula Komputer Dalam Kaedah Projek dan Masalah Dikemukakan Dalam masa 10 Jam? Bagaimana Mengajar Asas Pengaturcaraan Pemula Komputer Dalam Kaedah Projek dan Masalah Dikemukakan Dalam masa 10 Jam? Apr 02, 2025 am 07:18 AM

Bagaimana Mengajar Asas Pengaturcaraan Pemula Komputer Dalam masa 10 jam? Sekiranya anda hanya mempunyai 10 jam untuk mengajar pemula komputer beberapa pengetahuan pengaturcaraan, apa yang akan anda pilih untuk mengajar ...

Bagaimana cara menyalin seluruh lajur satu data ke dalam data data lain dengan struktur yang berbeza di Python? Bagaimana cara menyalin seluruh lajur satu data ke dalam data data lain dengan struktur yang berbeza di Python? Apr 01, 2025 pm 11:15 PM

Apabila menggunakan Perpustakaan Pandas Python, bagaimana untuk menyalin seluruh lajur antara dua data data dengan struktur yang berbeza adalah masalah biasa. Katakan kita mempunyai dua DAT ...

Bagaimana untuk mengelakkan dikesan oleh penyemak imbas apabila menggunakan fiddler di mana-mana untuk membaca lelaki-dalam-tengah? Bagaimana untuk mengelakkan dikesan oleh penyemak imbas apabila menggunakan fiddler di mana-mana untuk membaca lelaki-dalam-tengah? Apr 02, 2025 am 07:15 AM

Cara mengelakkan dikesan semasa menggunakan fiddlerevery di mana untuk bacaan lelaki-dalam-pertengahan apabila anda menggunakan fiddlerevery di mana ...

Bagaimanakah uvicorn terus mendengar permintaan http tanpa serving_forever ()? Bagaimanakah uvicorn terus mendengar permintaan http tanpa serving_forever ()? Apr 01, 2025 pm 10:51 PM

Bagaimanakah Uvicorn terus mendengar permintaan HTTP? Uvicorn adalah pelayan web ringan berdasarkan ASGI. Salah satu fungsi terasnya ialah mendengar permintaan HTTP dan teruskan ...

Bagaimana secara dinamik membuat objek melalui rentetan dan panggil kaedahnya dalam Python? Bagaimana secara dinamik membuat objek melalui rentetan dan panggil kaedahnya dalam Python? Apr 01, 2025 pm 11:18 PM

Di Python, bagaimana untuk membuat objek secara dinamik melalui rentetan dan panggil kaedahnya? Ini adalah keperluan pengaturcaraan yang biasa, terutamanya jika perlu dikonfigurasikan atau dijalankan ...

See all articles