【函数闭包的理解】

 最近学到 函数 闭包的时候,似懂非懂、迷迷糊糊的样子,很是头疼,今天就特意查了下关于闭包的知识,现将我自己的理解分享如下!

一、python 闭包定义

首先,关于闭包,百度百科是这样解释的:

  闭包是指可以包含自由(未绑定到特定对象)变量的代码块;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。“闭包” 一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域)。

      当然,这种学术性的解释对于我们小白来说,只能是更加的晦涩难懂。

从python对闭包的定义来说:

  必须是内部定义的函数,该函数包含对外部作用域而不是全局作用域名字的引用!

可能这么说还是有点难理解,那咱们换一种方式理解:

  python中的闭包从表现形式上可以解释为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包.

举个简单的例子来说明,可能会好理解一些:

 
def f1():
x = 12
def f2():
print(x)
return f2
f = f1()
print(type(f))
print(f)
f()
 

代码执行之后的结果如下:

<class 'function'>
<function f1.<locals>.f2 at 0x00000000028EC9D8>
12

结合这段简单的代码和定义来说明闭包:
如果在一个内部函数里:f2()就是这个内部函数,
对在外部作用域(但不是在全局作用域)的变量进行引用:x就是被引用的变量,x在外部作用域f1()里面,但不在全局作用域里。
则这个内部函数f2()就是一个闭包。

  从函数的定义角度出发:函数可以嵌套使用,可以把函数当成参数或返回值进行传递,函数也可以作为容器类型的元素,作为一个变量可以去赋值。

  在这个简单的例子当中,函数f1()中嵌套定义另一个函数f2(),内部的函数f2()引用了外部函数f1()的变量,函数f2()被当成夹带外部变量的 对象 返回给f1(),这样就形成一个闭包函数。

  实例化输出的时候 定义的 f=f1()中, 其实 f 就是函数f2()(不准确但是好理解)。这里需要注意的是,f 是一个函数名,加上()就能当作函数来用了。(因为f2()返回的是一串函数执行过程的包)

二、闭包的用途

1、闭包就是为了不动原函数里面的代码,还要给它增加‘新功能’的一种手段。

  最直接的例子就是爬取网站代码的闭包函数,不使用的时候,不用执行闭包函数,当需要爬取网站数据时,直接将定义的函数名后加上(),当作函数来使用。

from urllib.request import urlopen
def get(url):
def index():
return urlopen(url).read()
return index

python=get('http://www.python.org')
print(python) #主函数的内存
print(python()) #查看爬取网址之后,获得的网址的具体内容
print(python.__closure__[0].cell_contents) #将下载下来的内容翻译,以网址的形式显示下载的网站。

执行结果如下:

<function get.<locals>.index at 0x0000000002E45B70>
b'<!doctype html>\n<!--[if lt IE 7]>   <html class="no-js ie6 lt-ie7 lt-ie8 lt-ie9">   <![endif]-->\n<!--[if IE 7]>      <html class="no-js ie7 lt-ie8 lt-ie9">          <![endif]-->\n<!--[if IE 8]>      <html class="no-js ie8 lt-ie9">                 <![endif]-->\n<!--[if gt IE 8]><!--><html class="no-js" lang="en" dir="ltr">  <!--<![endif]-->\n\n<head>\n    <meta charset="utf-8">\n    <meta http-equiv="X-UA-Compatible" content="IE=edge">\n\n    <link rel="prefetch" href="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js">\n\n    <meta name="application-name" content="Python.org">\n    <meta name="msapplication-tooltip" content="The official home of the Python Programming Language">\n    <meta name="apple-mobile-web-app-title" content="Python.org">\n    <meta name="apple-mobile-web-app-capable" content="yes">\n    <meta name="apple-mobile-web-app-status-bar-style" content="black">\n\n    <meta name="viewport" content="width=device-width, initial-scale=1.0">\n    <meta name="HandheldFriendly" content="True">\n    <meta name="format-detection" content="telephone=no">\n    <meta http-equiv="cleartype" content="on">\n    <meta http-equiv="imagetoolbar" content="false">\n\n    <script src="/static/js/libs/modernizr.js"></script>\n\n    <link href="/static/stylesheets/style.css" rel="stylesheet" type="text/css" title="default" />\n    <link href="/static/stylesheets/mq.css" rel="stylesheet" type="text/css" media="not print, braille, embossed, speech, tty" />\n    \n\n    <!--[if (lte IE 8)&(!IEMobile)]>\n    <link href="/static/stylesheets/no-mq.css" rel="stylesheet" type="text/css" media="screen" />\n    \n    \n    <![endif]-->\n\n    \n    <link rel="icon" type="image/x-icon" href="/static/favicon.ico">\n    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="/static/apple-touch-icon-144x144-precomposed.png">\n    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="/static/apple-touch-icon-114x114-precomposed.png">\n    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="/static/apple-touch-icon-72x72-precomposed.png">\n    <link rel="apple-touch-icon-precomposed" href="/static/apple-touch-icon-precomposed.png">\n    <link rel="apple-touch-icon" href="/static/apple-touch-icon-precomposed.png">\n\n    \n    <meta name="msapplication-TileImage" content="/static/metro-icon-144x144-precomposed.png"><!-- white shape -->\n    <meta name="msapplication-TileColor" content="#3673a5"><!-- python blue -->\n    <meta name="msapplication-navbutton-color" content="#3673a5">\n\n    <title>Welcome to Python.org</title>\n\n    <meta name="description" content="The official home of the Python Programming Language">\n    <meta name="keywords" content="Python programming language object oriented web free open source software license documentation download community">\n\n    \n    <meta property="og:type" content="website">\n    <meta property="og:site_name" content="Python.org">\n    <meta property="og:title" content="Welcome to Python.org">\n    <meta property="og:description" content="The official home of the Python Programming Language">\n    \n    <meta property="og:image" content="https://www.python.org/static/opengraph-icon-200x200.png">\n    <meta property="og:image:secure_url" content="https://www.python.org/static/opengraph-icon-200x200.png">\n    \n    <meta property="og:url" content="https://www.python.org/">\n\n    <link rel="author" href="/static/humans.txt">\n\n    \n\n    \n    <script type="application/ld+json">\n     {\n       "@context": "http://schema.org",\n       "@type": "WebSite",\n       "url": "https://www.python.org/",\n       "potentialAction": {\n         "@type": "SearchAction",\n         "target": "https://www.python.org/search/?q={search_term_string}",\n         "query-input": "required name=search_term_string"\n       }\n     }\n    </script>\n\n    \n    <script type="text/javascript">\n    var _gaq = _gaq || [];\n    _gaq.push([\'_setAccount\', \'UA-39055973-1\']);\n    _gaq.push([\'_trackPageview\']);\n\n    (function() {\n        var ga = document.createElement(\'script\'); ga.type = \'text/javascript\'; ga.async = true;\n        ga.src = (\'https:\' == document.location.protocol ? \'https://ssl\' : \'http://www\') + \'.google-analytics.com/ga.js\';\n        var s = document.getElementsByTagName(\'script\')[0]; s.parentNode.insertBefore(ga, s);\n    })();\n    </script>\n    \n</head>\n\n<body class="python home" >
http://www.python.org
View Code

相关文章:

  • 2022-02-21
  • 2022-12-23
  • 2021-10-09
  • 2022-12-23
  • 2022-01-02
  • 2022-12-23
  • 2021-06-21
  • 2021-08-30
猜你喜欢
  • 2021-06-01
  • 2022-02-01
  • 2021-08-06
  • 2022-12-23
  • 2022-12-23
  • 2022-01-05
  • 2022-01-19
相关资源
相似解决方案