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. CentOS7 安装配置 MySQL 5.7

    1. 下载 yum 源文件 mysql80-community-release-el7-2.noarch.rpm https://dev.mysql.com/downloads/repo/yum/ 2 ...

  2. 特殊需求:EF 6.x如何比较TimeSpan格式的字符串?EF Core实现方式是否和EF 6.x等同?

    前言 我们知道C#中的TimeSpan对应SQL Server数据库中的Time类型,但是如果因为特殊需求数据库存储的不是Time类型,而是作为字符串,那么我们如何在查询数据时对数据库所存储的字符串类 ...

  3. 开源 , KoobooJson一款高性能且轻量的JSON框架

    KoobooJson - 更小更快的C# JSON序列化工具(基于表达式树构建) 在C#领域,有很多成熟的开源JSON框架,其中最著名且使用最多的是 Newtonsoft.Json ,然而因为版本迭代 ...

  4. Neutron vxlan network--L2 Population

    L2 Population 是用来提高 VXLAN 网络 Scalability 的.   通常我们说某个系统的 Scalability 好,其意思是: 当系统的规模变大时,仍然能够高效地工作. L2 ...

  5. python新手菜鸟之基础篇

    s=0 for i in range(1,101): s += i else: print(s) def main(n): '''打印菱形图形''' for i in range(n): print( ...

  6. Linux(Ubuntu)使用日记------markdown文档转化为word文档

    Linux(Ubuntu)使用日记------markdown文档转化为word文档

  7. Spring Boot环境下出现No operations allowed after connection close错误

    一个基于springcloud的微服务项目,详细配置: SpringCloud + SpringMVC+SpringData JPA+ MySql+Postgresql 其中项目配置了多数据源,前期开 ...

  8. cocos 场景制作流程

    前面的话 本文将详细介绍 cocos 场景制作流程 节点和组件 Cocos Creator 的工作流程是以组件式开发为核心的,组件式架构也称作组件-实体系统,简单的说,就是以组合而非继承的方式进行实体 ...

  9. 报错utf-8错误

    当python运行总报utf-8错误时, f = open('CI_CUSER_2019040116033031.txt')data_app = pd.read_csv(f)print(data_ap ...

  10. word里面对齐用Tab键

    1       Tab      组1 2             组2