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 变量作用域,闭包和装饰器的更多相关文章

  1. 21.python中的闭包和装饰器

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

  2. Python 中的闭包与装饰器

    闭包(closure)是函数式编程的重要的语法结构.闭包也是一种组织代码的结构,它同样提高了代码的可重复使用性. 如果在一个内嵌函数里,对在外部函数内(但不是在全局作用域)的变量进行引用,那么内嵌函数 ...

  3. python中的闭包和装饰器

    重新学习完了函数,是时候将其中的一些重点重新捋一捋了,本次总结的东西只有闭包和装饰器 1.闭包 闭包是python函数中的一个比较重要功能,一般闭包都是用在装饰器上,一般学完闭包就会去学习装饰器,这俩 ...

  4. 【Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数】

    一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(Firs ...

  5. Python作用域-->闭包函数-->装饰器

    1.作用域: 在python中,作用域分为两种:全局作用域和局部作用域. 全局作用域是定义在文件级别的变量,函数名.而局部作用域,则是定义函数内部. 关于作用域,我要理解两点:a.在全局不能访问到局部 ...

  6. Python记录9:函数4:名称空间作用域+闭包函数+装饰器

    ''' 一: 名称空间namespaces     名称空间就是存放名字与值绑定关系的内存空间 二: 名称空间分为三种     内置名称空间:         1. 特点: 存放是python解释器自 ...

  7. 第十七篇 Python函数之闭包与装饰器

    一. 装饰器 装饰器:可以拆解来看,器本质就是函数,装饰就是修饰的意思,所以装饰器的功能就是为其他函数添加附加功能. 装饰器的两个原则: 1. 不修改被修饰函数的源代码 2. 不修改被修饰函数的调用方 ...

  8. python 小兵(8)闭包和装饰器

    闭包"是什么,以及,更重要的是,写"闭包"有什么用处. (个人理解) 1."闭包"是什么 首先给出闭包函数的必要条件: 闭包函数必须返回一个函数对象 ...

  9. 轻松理解python中的闭包和装饰器(上)

    继面向对象编程之后函数式编程逐渐火起来了,在python中也同样支持函数式编程,我们平时使用的map, reduce, filter等都是函数式编程的例子.在函数式编程中,函数也作为一个变量存在,对应 ...

  10. python基础16_闭包_装饰器

    不了解是否其他语言也有类似 python 装饰器这样的东西. 最近才发现ECMAScript6也是有生成器函数的,也有 yield  generator 装饰器的基础知识是闭包: # 闭包:嵌套函数, ...

随机推荐

  1. HTML5移动端触摸事件

    一.移动端事件问题 1.click事件300ms延迟问题 2007年第一代iphone发布,移动端Safari首创双击缩放功能,原理是click一次后,经过300ms之后检测是否再有一次click,如 ...

  2. IdentityServer4实战 - JWT Issuer 详解

    一.前言 本文为系列补坑之作,拖了许久决定先把坑填完. 下文演示所用代码采用的 IdentityServer4 版本为 2.3.0,由于时间推移可能以后的版本会有一些改动,请参考查看,文末附上Demo ...

  3. React 系列教程2:编写兰顿蚂蚁演示程序

    简介 最早接触兰顿蚂蚁是在做参数化的时候,那时候只感觉好奇,以为是很复杂的东西.因无意中看到生命游戏的 React 实现,所以希望通过兰顿蚂蚁的例子再学习一下 React. 兰顿蚂蚁的规则非常简单: ...

  4. JS 转换HTML转义符

    JS转换HTML转义符   //去掉html标签 1 2 3 function removeHtmlTab(tab) {  return tab.replace(/<[^<>]+?& ...

  5. 分布式存储ceph——(6)ceph 讲解

    一.Ceph简介: Ceph是一种为优秀的性能.可靠性和可扩展性而设计的统一的.分布式文件系统.ceph 的统一体现在可以提供文件系统.块存储和对象存储,分布式体现在可以动态扩展.在国内一些公司的云环 ...

  6. MySQL二进预编译制安装

    +++++++++++++++++++++++++++++++++++++++++++标题:MySQL二进预编译制安装时间:2019年2月25日内容:MySQL二进制预编译安装重点:MySQL二进制预 ...

  7. 自己常用易忘的CSS样式

    鼠标小手:   cursor:pointer 点击边框消失:outline:none; ul li下划线以及点消失: list-style-type:none; span 超出内容为...:overf ...

  8. mongodb备份还原

    备份:mongodump mongodump常用参数 --db:指定导出的数据库 --collection:指定导出的集合 --excludeCollection:指定不导出的集合 --host :远 ...

  9. Python视频人脸检测识别

    案例 这里我们还是使用 opencv 中自带了 haar人脸特征分类器,通过读取一段视频来识别其中的人脸. 代码实现:   动图有点花,讲究着看吧:   如果是捕捉摄像头,只需要改变以下代码即可: c ...

  10. pc端手機端自適應佈局方案

    https://blog.csdn.net/chose_DoIt/article/details/80424341 https://blog.csdn.net/cxz792116/article/de ...