闭包

07-04 函数对象与闭包

夙愿已清 提交于 2019-12-25 17:28:07
[TOC] 一 函数对象 函数对象指的是函数可以被当做’数据’来处理,具体可以分为四个方面的使用,我们如下 插图:恶搞图26 1.1 函数可以被引用 >>> def add(x,y): ... return x+y ... >>> func=add >>> func(1,2) 3 1.2 函数可以作为容器类型的元素 >>> dic={'add':add,'max':max} >>> dic {'add': <function add at 0x100661e18>, 'max': <built-in function max>} >>> dic['add'](1,2) 3 1.3 函数可以作为参数传入另外一个函数 >>> def foo(x,y,func): ... return func(x,y) ... >>> foo(1,2,add) 3 1.4 函数的返回值可以是一个函数 >>> def bar(): ... return add ... >>> func=bar() >>> func(1,2) 3 插图:恶搞图27 二 闭包函数 2.1 闭与包 基于函数对象的概念,可以将函数返回到任意位置去调用,但作用域的关系是在定义完函数时就已经被确定了的,与函数的调用位置无关。 x=1 def f1(): def f2(): print(x) return f2 def f3():

Python题库 - 简答题

落爺英雄遲暮 提交于 2019-12-25 05:08:49
1.命名空间和作用域的关系 命名空间定义了在某个作用域内变量名和绑定值之间的对应关系,命名空间是键值对的集合,变量名与值是一一对应关系。作用域定义了命名空间中的变量能够在多大范围内起作用。 2.装饰器函数的作用?写一个装饰器程序 在不修改原函数及其调用方式的情况下对原函数功能进行扩展。 def outer ( f ) : def inner ( ) : print ( "************" ) f ( ) print ( "************" ) return inner @outer def func ( ) : print ( "巴啦啦小魔仙" ) func ( ) 3.闭包的形成要件是什么,写一个闭包函数 闭包函数必须有内嵌函数、内嵌函数必须要引用外层函数的变量、闭包函数返回内嵌函数的地址(函数名称)。 def adder ( x ) : def wrapper ( y ) : return x + y return wrapper adder5 = adder ( 5 ) # 输出 15 adder5 ( 10 ) # 输出 11 adder5 ( 6 ) 4.简述try、except语句的用法 程序先执行try中的代码,如果try中代码没有出错,则不会执行except中的异常代码。如果try中的代码出错了,则执行exception中的异常代码。 5

golang学习笔记---函数、方法和接口

谁都会走 提交于 2019-12-25 04:22:24
函数: 对应操作序列,是程序的基本组成元素。 函数有具名和匿名之分: 具名函数一般对应于包级的函数,是匿名函数的一种特例,当匿名函数引用了外部 作用域中的变量时就成了闭包函数,闭包函数是函数式编程语言的核心。方法是绑 定到一个具体类型的特殊函数,Go语言中的方法是依托于类型的,必须在编译时静 态绑定 接口: 定义了方法的集合,这些方法依托于运行时的接口对象,因此接口对 应的方法是在运行时动态绑定的。 Go程序函数启动顺序的示意图: 要注意的是,在 main.main 函数执行之前所有代码都运行在同一个goroutine,也 就是程序的主系统线程中。 因此,如果某个 init 函数内部用go关键字启动了新的 goroutine的话,新的goroutine只有在进入 main.main 函数之后才可能被执行到。 函数 在Go语言中,函数是第一类对象,我们可以将函数保持到变量中。函数主要有具名 和匿名之分,包级函数一般都是具名函数,具名函数是匿名函数的一种特例 // 具名函数 func Add(a, b int) int {   return a+b } // 匿名函数 var Add = func(a, b int) int {   return a+b } Go语言中的函数可以有多个参数和多个返回值,参数和返回值都是以传值的方式和 被调用者交换数据。在语法上,函数还支持可变数量的参数

Swift - 懒加载(lazy initialization)

落爺英雄遲暮 提交于 2019-12-24 19:03:46
Swift中是存在和OC一样的懒加载机制的,在程序设计中,我们经常会使用 懒加载 ,顾名思义,就是用到的时候再开辟空间 懒加载 格式: lazy var 变量: 类型 = { 创建变量代码 }() 懒加载的写法本质上是定义并执行一个闭包 // 含义: 当dataList被使用到时, 就会执行等号后面的闭包 // 所以等号后面的闭包的()是必须写的, 如果不写就会报错 // 注意点: 如果写懒加载, 那么修饰符必须用var lazy var dataList:[String] = { print("我被加载了") return ["lnj", "lmj", "zs"] }() lazy var satatuses: [String] = self.loadStatus() func loadStatus() -> [String] { print("我被加载了") return ["lnj", "lmj", "zs"] } // 懒加载 private lazy var inputeTextField: UITextField = { let inputeTextField = UITextField () inputeTextField. keyboardType = . NumberPad /* 8 种键盘风格: UIKeyboardTypeDefault, // 默认键盘

带你彻底了解闭包以及其原理

拈花ヽ惹草 提交于 2019-12-24 05:02:27
闭包一直是许多初学者的难题,网上对闭包的讲解也是众说纷纭,但还是许多人不能明白。 下面我通过五个简单例子,让你明白闭包原理。 第一个例子 <script> var i = 0; document.onclick = addNumber; function addNumber(){ i++; document.title =i; }; </script> 第一个例子都能看懂,是个简简单单的实现 i 累加。无需多说,我们继续看第二个例子。 第二个例子 <script> document.onclick = addNumber; function addNumber(){ var i = 0; i++; document.title =i; }; </script> 第二个例子:我们会发现 i 这时候无法实现累加,一直显示是1。这是为什么? 原因是: 1、第一个例子的 i 定义在函数外面,它在一个叫做"全局作用域"的区域里面。"全局作用域"只会在浏览器窗口关闭或页面刷新的时候进行关闭。(我们跟第二个例子对比下就知道全局作用域)。 2、第二个例子的 i 定义在函数里面,它在一个叫做"局部作用域"的区域里面。(局部作用域是我自己命名的,方便理解)。"局部作用域"会在函数被调用的时候创建,而在函数运行结束的时候关闭(并且里面创建的变量跟函数也会被删掉–垃圾回收机制)。 3、通过上面的说法

C++11新特性中的匿名函数Lambda表达式的汇编实现分析(一)

為{幸葍}努か 提交于 2019-12-23 12:52:48
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> Constructs a closure: an unnamed function object capable of capturing variables in scope. —— Lambda functions (since C++11) [cppreference.com] 按照C++11标准的说法,lambda表达式的标准格式如下: [ capture ] ( params ) mutable exception attribute -> ret { body } // (1) 完整的声明 [ capture ] ( params ) -> ret { body } //(2) 一个常lambda的声明:按副本捕获的对象不能被修改。 [ capture ] ( params ) { body } // (3) 省略后缀返回值类型:闭包的operator()的返回值类型是根据以下规则推导出的:如果body仅包含单一的return语句,那么返回值类型是返回表达式的类型(在此隐式转换之后的类型:右值到左值、数组与指针、函数到指针)否则,返回类型是void [ capture ] { body } //(4) 省略参数列表:函数没有参数,即参数列表是() capture -

Effective C++: lambda表达式与闭包.

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-23 12:40:10
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> C++11:带来了lambda表达式.那么让我们一起来探究吧. lambda捕获列表: 1, [] 空的捕获列表,lambda不能使用所在函数内的任何变量. 2, [names] names是一个用逗号分隔的名字列表, 这些名字都是lambda所在函数的局部变量,默认情况都是以拷贝的性质捕获(capture)的,如果这些名字前面都有&那么就都是以引用的形式捕获的. 3, [&] 隐式的以引用形式的列表捕获 ,lambda体内所有的来自函数的实体都是以引用的形式捕获. 4, [=] 隐式的以拷贝形式的列表捕获 ,lambda体内的所有来自函数的实体都是以值的形式捕获的. 5, [&, names] names是一个逗号分隔的名字列表,包含0个或多个来自函数的变量,这些变量都是以拷贝的形式被捕获的,names中变量的名字前面不能使用&. 那些没有出现在names中,却出现在了lambda函数体变量都是以引用的形式捕获的. 6, [=, names] names是一个逗号分隔的名字列表,这些名字都是lambda所在的函数的局部变量,且这些名字前面必须有&,列表内的变量都是以引用的形式捕获的, 那些没有出现在names中,却出现在lambda函数体中的变量都是以拷贝的形式捕获的. 7, [name]

JavaScript--匿名函数和闭包(16)

≡放荡痞女 提交于 2019-12-23 05:18:44
// 匿名函数:没有名字的函数; // 闭包:可访问一个函数作用域里的变量的函数; 一 匿名函数 1 // 普通函数 2 function box(){ // 函数名是box; 3 return 'Lee'; 4 } 5 box(); // =>Lee; 调用函数; 6 // 匿名函数 7 function(){ // 匿名函数,会报错; 8 return 'Lee'; 9 } 10 // 通过表达式自我执行 11 (function(name){ 12 console.log(name); // =>Lee; 13 })("Lee"); // "()"表示执行函数,并且可以传参; 14 // 把匿名函数赋值给变量 15 var box = function(){ // 将匿名函数赋给变量; 16 return 'Lee'; 17 }; 18 console.log(box()); // 调用方式和函数调用相似; 19 // 函数里的匿名函数 20 function box(){ 21 return function(name){ // 函数里的匿名函数,产生闭包; 22 return name; 23 }; 24 }; 25 console.log(box()("Lee")); // 函数box()调用匿名函数,并传参; 二 闭包 // 闭包

关于 [lambda x: x*i for i in range(4)] 理解

試著忘記壹切 提交于 2019-12-22 13:08:20
题目: lst = [lambda x: x*i for i in range(4)] res = [m(2) for m in lst] print res 实际输出:[6, 6, 6, 6] 想要输出 [0, 2, 4, 6] 应该怎么改?如下: lst = [lambda x, i=i: x*i for i in range(4)] res = [m(2) for m in lst] print res 这个问题涉及到了Python的闭包及延时绑定的知识(Python作用域)。 在Python核心编程里,闭包的定义如下: 如果在一个内部函数里,对外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认定是闭包。 总结为三点: 1、是一个内嵌函数 2、对外部函数变量引用 3、外部函数返回内嵌函数 简单的闭包例子: def counter(start_at=0): count = [start_at] def incr(): count[0] += 1 return count[0] return incr 上面的那道题,可以写成这样: def func(): fun_list = [] for i in range(4): def foo(x): return x*i fun_list.append(foo) return fun_list for m in func