Python 变量作用域,闭包和装饰器
from dis import dis b = 6 def f1(a):
print(a)print(b)
b = 9 f1(3) print(dis(f1)) # dis模块可以查看python函数字节码
解决报错的方案一:申明b全局变量
from dis import dis b = 6 def f1(a):
print(a)
global b
print(b)
b = 9 f1(3) print(dis(f1)) # dis模块可以查看python函数字节码
闭包
计算移动平均值
class Averager:
def __init__(self):
self.series = []
def __call__(self, new_value):
self.series.append(new_value)
total = sum(self.series) # 汇总
return total/len(self.series) # 求平均值
avg = Averager()
print(avg(10))
print(avg(11))
print(avg(12))
通过高阶函数实现
def make_averager():
series = [] def averager(new_value):
series.append(new_value)
total = sum(series)
return total/len(series)
return averager avg = make_averager()
print(avg(10))
print(avg(11))
print(avg(12)) print(avg.__code__.co_varnames) # 打印局部变量
print(avg.__code__.co_freevars) # 打印自由变量
print(avg.__closure__) # series的绑定在返回的函数的__closure__属性中
print(avg.__closure__[0].cell_contents) # 这些元素是cell对象,有个cell_contents属性,保存着真正的值 # 综上,闭包是一种函数,它会保留定义函数时存在的自由变量的绑定,这样调用函数时,虽然定义作用域不可用了,但是仍能使用那些绑定 # 注意,只有嵌套在其他函数中的函数才可能需要处理不在全局作用域中的外部变量
如果是赋值操作呢?
def make_averager():
count = 0
total = 0 def averager(new_value):
count += 1
total +=new_value
return total / count
return averager
# 这里直接执行会报错,因为count += 1 相当于count = count + 1,因此当在averager的定义体内为count赋值,会把count变成局部变量。total变量也是同理
解决方案
# 引入nonlocal声明,作用是把变量标记为自由变量
def make_averager():
count = 0
total = 0 def averager(new_value):
nonlocal count, total
count += 1
total += new_value
return total / count return averager
装饰器代码一
def deco(func):
def inner(*args, **kwargs):
print('this is inner')
return inner @deco
def foo():
print('this is foo') foo() # this is inner
print(foo.__name__) # inner
装饰器代码二
def wrap(func):
def deco(*args, **kwargs):
print('deco ==> ', args, kwargs)
func(*args, **kwargs)
print('this is inner')
return deco @wrap
def foo(*args, **kwargs):
print('this is foo') foo()
# deco ==> () {}
# this is foo
# this is inner print(foo.__name__) # deco
装饰器代码三
from functools import wraps def wrap(func):
@wraps(func)
def deco(*args, **kwargs):
print('deco ==> ', args, kwargs)
func(*args, **kwargs)
print('this is inner')
return deco @wrap
def foo(*args, **kwargs):
print('this is foo') foo()
# deco ==> () {}
# this is foo
# this is inner print(foo.__name__) # foo
有空讲解0.0
Python 变量作用域,闭包和装饰器的更多相关文章
- 21.python中的闭包和装饰器
python中的闭包从表现形式上定义(解释)为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure). 以下说明主要针对 python ...
- Python 中的闭包与装饰器
闭包(closure)是函数式编程的重要的语法结构.闭包也是一种组织代码的结构,它同样提高了代码的可重复使用性. 如果在一个内嵌函数里,对在外部函数内(但不是在全局作用域)的变量进行引用,那么内嵌函数 ...
- python中的闭包和装饰器
重新学习完了函数,是时候将其中的一些重点重新捋一捋了,本次总结的东西只有闭包和装饰器 1.闭包 闭包是python函数中的一个比较重要功能,一般闭包都是用在装饰器上,一般学完闭包就会去学习装饰器,这俩 ...
- 【Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数】
一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(Firs ...
- Python作用域-->闭包函数-->装饰器
1.作用域: 在python中,作用域分为两种:全局作用域和局部作用域. 全局作用域是定义在文件级别的变量,函数名.而局部作用域,则是定义函数内部. 关于作用域,我要理解两点:a.在全局不能访问到局部 ...
- Python记录9:函数4:名称空间作用域+闭包函数+装饰器
''' 一: 名称空间namespaces 名称空间就是存放名字与值绑定关系的内存空间 二: 名称空间分为三种 内置名称空间: 1. 特点: 存放是python解释器自 ...
- 第十七篇 Python函数之闭包与装饰器
一. 装饰器 装饰器:可以拆解来看,器本质就是函数,装饰就是修饰的意思,所以装饰器的功能就是为其他函数添加附加功能. 装饰器的两个原则: 1. 不修改被修饰函数的源代码 2. 不修改被修饰函数的调用方 ...
- python 小兵(8)闭包和装饰器
闭包"是什么,以及,更重要的是,写"闭包"有什么用处. (个人理解) 1."闭包"是什么 首先给出闭包函数的必要条件: 闭包函数必须返回一个函数对象 ...
- 轻松理解python中的闭包和装饰器(上)
继面向对象编程之后函数式编程逐渐火起来了,在python中也同样支持函数式编程,我们平时使用的map, reduce, filter等都是函数式编程的例子.在函数式编程中,函数也作为一个变量存在,对应 ...
- python基础16_闭包_装饰器
不了解是否其他语言也有类似 python 装饰器这样的东西. 最近才发现ECMAScript6也是有生成器函数的,也有 yield generator 装饰器的基础知识是闭包: # 闭包:嵌套函数, ...
随机推荐
- .NET程序员我是如何通过一个产品在2年内买车买房
刚开始写博客不足之处望大家多多指点,少一些质疑多一些帮助,我们就能成为朋友. 我写博客的目的其实很简单就是为了分享知识,如有幸能申请当MVP那是最好不过了,这个过程对于“大牛”来说很快,但对于我来说估 ...
- iOS 使用Instruments的工具小结
使用Instruments的工具 iOSXcodeInstrumentsInstruments是一个官方提供的强大的性能调试工具集. 1.Blank(空模板):创建一个空的模板,可以从Library库 ...
- Spring Boot – Jetty配置
前言 默认情况下,Spring Boot会使用内置的tomcat容器去运行应用程序,但偶尔我们也会考虑使用Jetty去替代Tomcat:对于Tomcat和Jetty,Spring Boot分别提供了对 ...
- js面向对象学习
纯属笔记,加强记忆,不是教程,欢迎纠错,没有逻辑,不太适合学习使用. -------------- 继承多态等太多概念难以理解,还是从实践中慢慢学吧!争取能大致看懂网上的开源的代码. -------- ...
- Promise async-await 异步解决方案
1.简介: async和await在干什么,async用于申明一个function是异步的,而await可以认为是async wait的简写,等待一个异步方法执行完成. 2.基本语法 在C ...
- 洛谷P2756 飞行员配对方案问题
二分图裸题,找他的最大匹配即可 #include<bits/stdc++.h> using namespace std; int n,m,ans; ; int to[N]; struct ...
- python操作随笔
# -*- encoding: utf-8 -*-import urllib2from bs4 import BeautifulSoupimport re f1 = open('E:/1.txt')l ...
- 虚拟机ubuntu设置静态IP与主机、外网互ping配置流程
方案一.VMnet8(NAT模式) 1.选择自定义模式,VMnet8(NAT模式) 2.进入虚拟机,设置静态IP之前确认三者可互ping通,命令ifconfig,查看当前的IP 3.主机通过命令ipc ...
- springboot 配置mybatis
- AB PLC教程
把文档贴到Blog.BBS或个人站等: 复制 预览 普通尺寸(450*500pix) 较大尺寸(630*500pix)