首页 > 编程语言 >python 闭包变量不允许write,要使用nonlocal

python 闭包变量不允许write,要使用nonlocal

时间:2023-08-03 22:01:36浏览次数:35  
标签:闭包 do spam python global nonlocal add print def

 

以下是一段简单的闭包代码示例:

def foo():
    m=3
    n=5
    def bar():
        a=4
        return m+n+a
    return bar

>>>bar =  foo()
>>>bar()
12


是可以的!但是:
def foo():
    m=3
    n=5
    def bar():
        a=4
        m += 1 #不可以!!!
        return m+n+a
    return bar

>>>bar =  foo()
>>>bar()
12


python中global 和 nonlocal 的作用域

python引用变量的顺序: 当前作用域局部变量->外层作用域变量->当前模块中的全局变量->python内置变量 。

一 global

global关键字用来在函数或其他局部作用域中使用全局变量。但是如果不修改全局变量也可以不使用global关键字。

1 gcount = 0
2 
3 def global_test():
4     gcount+=1
5     print (gcount)
6 global_test()

D:\Python34\python.exe E:/PycharmProjects/Day3/globaltest.py
Traceback (most recent call last):
File "E:/PycharmProjects/Day3/globaltest.py", line 6, in <module>
global_test()
File "E:/PycharmProjects/Day3/globaltest.py", line 4, in global_test
gcount+=1
UnboundLocalError: local variable 'gcount' referenced before assignment

Process finished with exit code 1

第一行定义了一个全局变量,(可以省略global关键字)。

在global_test 函数中程序会因为“如果内部函数有引用外部函数的同名变量或者全局变量,并且对这个变量有修改.那么python会认为它是一个局部变量,又因为函数中没有gcount的定义和赋值,所以报错。

 

二、声明全局变量,如果在局部要对全局变量修改,需要在局部也要先声明该全局变量:

gcount = 0
 
def global_test():
global  gcount
gcount+=1
print (gcount)
global_test()

  如果在函数中声明 gcount 是全局变量,即可对其进行修改。 正确输出 1 。

 

三、 在局部如果不声明全局变量,并且不修改全局变量。则可以正常使用全局变量:

gcount = 0
 
def global_test():
print (gcount)
global_test()

  如果在局部不修改全局变量,程序正确输出 0 。

 

四、nonlocal关键字用来在函数或其他作用域中使用外层(非全局)变量。

def make_counter():  
count = 0 
def counter():  
nonlocal count  
count += 1 
return count  
return counter  
 
def make_counter_test():  
mc = make_counter()  
print(mc())
print(mc())
print(mc())
 
make_counter_test()

  输出:

   1

   2

   3

五、

def scope_test():
def do_local():
spam = "local spam" #此函数定义了另外的一个spam字符串变量,并且生命周期只在此函数内。此处的spam和外层的spam是两个变量,如果写出spam = spam + “local spam” 会报错
def do_nonlocal():
nonlocal  spam        #使用外层的spam变量
spam = "nonlocal spam"
def do_global():
global spam
spam = "global spam"
spam = "test spam"
do_local()
print("After local assignmane:", spam)
do_nonlocal()
print("After nonlocal assignment:",spam)
do_global()
print("After global assignment:",spam)
 
scope_test()
print("In global scope:",spam)

  输出是:

After local assignmane: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam

 

 

在函数 add_b 内 global 定义的变量 b,只能在 函数 do_global 内引用, 如果要在 do_global 内修改,必须在 do_global 函数里面声明 global  b ,表明是修改外面的 全局变量 b :

def add_b():
    global  b
    b = 42
    def do_global():
        global  b
        b = b + 10
        print(b)
    do_global()
    print(b)
add_b()

 

global 定义的变量,表明其作用域在局部以外,即局部函数执行完之后,不销毁 函数内部以global定义的变量:

def add_a():
    global  a
    a =   3
add_a()
print(a)

输出 3 。

 

 

def add_b():
    global  b
    b = 42
    def do_global():
        global  b
        b = b + 10
        print(b)
    do_global()
    print(b)
add_b()
print(b)

以上代码输出:

52

52

52

 

def add_b():
    global  b
    b = 42
    def do_global():
        #global  b
        b = b + 10
        print(b)
    do_global()
    print(b)
add_b()

以上代码报错:

Traceback (most recent call last):
File "E:/PycharmProjects/OOP/exe1.py", line 42, in <module>
add_b()
File "E:/PycharmProjects/OOP/exe1.py", line 40, in add_b
do_global()
File "E:/PycharmProjects/OOP/exe1.py", line 38, in do_global
b = b + 10
UnboundLocalError: local variable 'b' referenced before assignment

原因: global 定义的 b ,只能引用,不能修改。

 

def add_b():
    global  b
    b = 42
    def do_global():
        global  a
        a = b + 10
        print(b)
    do_global()
    print(a)
add_b()
print("a = %s , b = %s " %(a, b))

输出:

42
52
a = 52 , b = 42

 

 

 

def add_b():
    #global  b
    b = 42
    def do_global():
        global  b
        b =  10
        print(b)
    do_global()
    print(b)
add_b()
print(" b = %s " % b)

以上代码输出:

10
42
b = 10

 

 

def add_b():
    #global  b
    b = 42
    def do_global():
        nonlocal  b
        b =  10
        print(b)
    do_global()
    print(b)
add_b()

以上代码输出:

10

10

 

def add_b():
#global  b
b = 42
def do_global():
nonlocal  b
b =  10
print(b)
do_global()
print(b)
add_b()
print(" b = %s " % b)

 

  以上代码报错:

print(" b = %s " % b)
NameError: name 'b' is not defined

说明: nonlocal  适用于在局部函数 中 的局部函数, 把最内层的局部 变量设置成外层局部可用,但是还不是全局的。

 

def add_b():
    #global  b
    #b = 42
    def do_global():
        nonlocal  b
        b =  10
        print(b)
    do_global()
    #print(b)
add_b()

以上代码报错:

File "E:/PycharmProjects/OOP/exe1.py", line 37
nonlocal b
SyntaxError: no binding for nonlocal 'b' found

nonlocal 要绑定一个局部变量。

标签:闭包,do,spam,python,global,nonlocal,add,print,def
From: https://blog.51cto.com/u_11908275/6953811

相关文章

  • python 代码混淆工具汇总
    pyminifierPyminifierisaPythoncodeminifier,obfuscator,andcompressor.NoteForthelatest,completedocumentation:http://liftoff.github.io/pyminifier/Forthelatestcode:https://github.com/liftoff/pyminifierOverviewWhenyouinstallpyminifierit......
  • Python安装与配置
    一、Windows下安装Python3。官网地址:https://www.python.org/下载地址:https://www.python.org/ftp/python/3.6.4/python-3.6.4-amd64.exe二、安装1、为了不去设置环境变量,我选择Customizeinstallation安装,并且勾选AddPython3.6toPATH。   2、选择安装路径,我安装......
  • python coding style guide 的快速落地实践——业内python 编码风格就pep8和谷歌可以
    pythoncodingstyleguide的快速落地实践机器和人各有所长,如codingstyle检查这种可自动化的工作理应交给机器去完成,故发此文帮助你在几分钟内实现codingstyle的自动检查。1.有哪些著名的PythonCodingStyleGuidePEP8https://www.python.org/dev/peps/pep-0008/发明Python语言......
  • SSL 证书过期巡检脚本 (Python 版)
    哈喽大家好,我是咸鱼之前写了个shell版本的SSL证书过期巡检脚本(文章:《SSL证书过期巡检脚本》),后台反响还是很不错的那么今天咸鱼给大家介绍一下python版本的SSL证书过期巡检脚本(完整代码在文末)思路导入相关模块importsslimportsocketimporttimefromdatetime......
  • x86_64 ubuntu22.04环境下编译版本python3.13.0 alpha 0源码——python3.13.0 alpha 0
      python3.13.0alpha0版本源码编译: 环境——x86_64ubuntu22.04系统: 1.源码下载:gitclonehttps://github.com/python/cpython 2.修改apt源地址:编辑文件:sudovim/etc/apt/sources.list添加内容:deb-srchttp://archive.ubuntu.com/ubuntu/jammymain......
  • PEP 703作者给出的一种no-GIL的实现——python3.9的nogil版本
    PEP703的内容是什么,意义又是什么呢?可以说python的官方接受的no-GIL提议的PEP就是PEP703给出的,如果GIL帧的从python中移除那么可以说对整个python生态圈将有着跨越性发展的意义。  ====================================================  PEP703地址:https://peps.p......
  • 【python系列】手把手教你在pypi发布自己的包-他人可pip下载
    前言最近在写一个接口执行引擎用作于接口自动化测试平台的核心。看了挺多资料,做了挺多事情,学了挺多乱七八糟的知识,笔记记得乱糟糟的,以至于一直没有整理发文(啊其实我就是懒),各位见谅。正文如下目前该引擎可以通过pip直接下载,但内容我还在写,预计这个月会完成(大概也许可能可以。)pypi发......
  • 自动生成python程序调用关系逻辑图
    前言你是否因为看一个程序或者运行一个框架,不知道他的运行流程?自己想写一个运行流程却觉得麻烦无从下手?graphviz+pycallgraph帮你绘制让领导看了都拍桌子称赞你的python程序逻辑调用关系图!先来看一下我这段时间在写的一个框架的部分流程吧~密密麻麻,真的哈人,完整的更哈人。狗看了都......
  • python-windows命令行启动appium及杀掉对应接口进程
    文章目录windows命令行启动appium及杀掉对应接口进程一.环境配置1.安装命令行版appium2.安装appium-doctor检测3.python安装Appium-Python-Client:4.定位uiautomatorviewer.bat5.查看主包名主类名Activity二.python-appium启动app1.appium启动一加计算器相关参数:2.windows查看端口......
  • python面试题
    基础篇1.为什么学习PythonPython语言简单易懂,上手容易,随着AI风潮,越来越火2.解释型和编译型语言的区别编译型语言:把做好的源程序全部编译成二进制的可运行程序。然后,可直接运行这个程序。如:C,C++解释型语言:把做好的源程序翻译一句,然后执行一句,直至结束!如:Python,(Java有些......