首页 > 编程语言 >python中的 nonlocal 和 global

python中的 nonlocal 和 global

时间:2022-12-04 22:56:22浏览次数:67  
标签:count func2 func1 函数 python global nonlocal num def

做 leetcode 1774时候遇到的一个bug

class Solution:
    def closestCost(self, baseCosts: List[int], toppingCosts: List[int], target: int) -> int:
        ans = min(baseCosts)
        if ans >= target:
            return ans

        def dfs(cur, temp):
            nonlocal ans
            # cur是 topping 的下标
            if abs(ans - target) < temp - target:
                return
            if abs(temp - target) < abs(ans - target):
                ans = temp
            if abs(temp - target) == abs(ans - target):
                ans = min(temp, ans)
            if abs(temp - target) == 0:
                return temp
            if cur == len(toppingCosts):
                return 
            dfs(cur + 1, temp)
            dfs(cur + 1, temp + toppingCosts[cur])
            dfs(cur + 1, temp + 2 * toppingCosts[cur])
        for i in baseCosts:
            dfs(0, i)
        return ans

刚开始写成global ans, 发现报错, 因为ans还是定义在外层的函数中, 并不是全局变量

贴一下博客解释
https://www.cnblogs.com/jwyqn/p/14584766.html
nonlocal 是 python 内置的关键字,其作用是可以在内层函数内声明一个外部函数的变量,它的功能与global 相似,nonlocal 本质上是介于 全局作用域和局部作用域之间的,它仅在函数的嵌套使用时才起作用。




global
global 是 python 内置的关键字 其作用是可以在函数内声明一个全局变量,在上一章我们说到了,在局部空间里不能直接修改全局作用域的变量,其实修改是可以的,只是需要事先声明,也就是要告诉解释器 这是一个全局变量,一会修改的时候你就到全局去找它吧。

在函数内部修改全局变量
实例1:

num = 0
def func():
    num += 1
    
func()

结果:UnboundLocalError: local variable 'count' referenced before assignment

原因:在局部修改全局变量 num 时没有事先声明 num 是一个全局变量。所以报错

该实例具体报错原因前面 Python作用域中将 Local 局部作用域中 实例2 的时候已经讲解过了,这里不再赘述

实例2:

num = 0
def func():
    num = 1
    print("in loclas ", num)  # 打印函数内部的 num
print("in globals ", num)  # 打印全局的 num
func()

结果:

in globals 0
in loclas 1
原因:func 里的变量 num 之所以结果是 1 并不是修改了全局变量,而是在局部名称空间里重新创建了一个 num 变量,并给其赋值 1 ,函数内部也就是局部作用域可以引用全局作用域的变量,但是不能直接修改。

实例3:

num = 0
def func():
    global num  # 声明一个全局变量
    num += 1
    print("in loclas ", num)  # 打印函数内部的 num
print("in globals ", num)  # 打印全局的 num
func()

结果:

in globals 0

in loclas 1

原因:在局部修改全局变量之前,先声明了这个变量的来源 global num 就是告诉解释器 变量 num 是一个全局变量,如果一会在函数里面有针对num 这个变量的修改操作就去全局名称空间里面寻找这个num

小结:

通过上面两个实例我们可以得出,Python 在局部可以引用全局变量 但是不能直接修改
Python 在 局部作用域要对一个全局作用域的变量进行修改或需要事先声明这是一个全局变量。
函数嵌套
Python 函数嵌套是指 一个函数里面再定义一个函数

def func1():
    x = 100
    def func2():
        print(x)
    func2()
func1()

结果:func1 >>> 100

这个就是函数的嵌套,我们先来看一下嵌套函数的执行顺序

这是详细版本

这是简化版本
你也可以理解为python程序在执行过程中是从上往下顺序执行的,如果遇到def function_name():python会直接跳过函数这段代码不会执行里面的代码
总之函数在Python程序中的执行顺序一定看得懂,不然后面有很多东西你会跟不上的。
nonlocal
nonlocal 是 python 内置的关键字,其作用是可以在内层函数内声明一个外部函数的变量,它的功能与global 相似,nonlocal 本质上是介于 全局作用域和局部作用域之间的,它仅在函数的嵌套使用时才起作用。

实例1:

def func1():
    count = 1
    def func2():
        count += 1
    func2()
func1()

结果:UnboundLocalError: local variable 'count' referenced before assignment

原因:原因跟上面 实例1 一样只不过不是全局变量而是 内层函数 修改外部函数前没有事先声明 python解释器在内层函数里找不到 count 变量就会直接报错

实例2:

def func1():
    count = 1
    def func2():
        count = 100
        print("in func2 ", count)  # 打印内层函数的count
    func2()
    print("in func1 ", count)  # 打印外层函数的count
func1()  

结果:

in func2 100
in func1 1
原因:内层函数与外层函数的关系就和全局和局部的关系一样,内层函数可以引用外层函数的变量,但是无法直接修改。

注意:func2 里的 count = 100 并不是修改 外部函数的 count 变量,当你在内层函数里写上变量名并给其赋值的时候,python如果看到局部名称空间里没有这个变量名称,它就会创建一个新的变量并赋值。

实例3:

def func1():
    count = 1
    def func2():
        nonlocal count
        count += 100
        print("in func2 ", count)
    func2()
    print("in func1 ", count)
func1()

结果:

in func2 101
in func1 101
原因:因为在修改变量 count 之前 事先声明了这个 count 是来自外层函数的 count ,解释器在func2 里执行到 count += 100 的时候就会直接到外层函数去寻找这个count 变量。不管你套了多少层函数,python都只会按照就近原则,即最靠近 引用该变量的这个函数的 count ,但只要你声明了nonlocal python就不会去全局名称空间搜索这个 count 变量,如果在外层函数查找不到这个变量就报错。

标签:count,func2,func1,函数,python,global,nonlocal,num,def
From: https://www.cnblogs.com/islch/p/16951093.html

相关文章

  • Python基础之函数提高
    一、变量作⽤域变量作⽤域指的是变量⽣效的范围,主要分为两类:局部变量和全局变量。1、局部变量所谓局部变量是定义在函数体内部的变量,即只在函数体内部⽣效。deftestA():a......
  • Python 使用MongoDB & MongoDB 工具的封装
    Python使用MongoDB补充:操作之前首先在虚拟机或者服务器端启动MongoDB;#重新加载配置,并启动mongodbsudosystemctldaemon-reloadsudosystemctlstartmongod#......
  • python自动化办公初探之桌牌制作
    前言:开会用的桌牌,制作起来非常麻烦,要根据参会人员的不同,制作不同的桌牌。如果参会人员非常多,制作就变的更麻烦。通过python中的xlrd和docxtpl模块可以自动的快速生成桌牌,省......
  • Centos7.x安装Python3(优化方法)
    安装相应的编译工具建议在root下操作,会方便很多,一定要安装,否则编译安装会报错。yum-ygroupinstall"Developmenttools"yum-yinstallzlib-develbzip2-developens......
  • Centos7.x将Python2升级到Python3
    查看Python版本python-V更新yum源yumupdate安装依赖yuminstallyum-utilsyum-builddeppython3下载pythonwgethttps://www.python.org/ftp/python/3.8.5/Py......
  • 离线安装python库
    B站看到了水哥的自动化办公视频(5分钟,教你做个自动化软件拿来办公)但因为用的是内网,所以没法直接pipinstall所以这里我们离线安装安装的就是和视频中相关的几个库相关环......
  • python打包指南
    在项目的根目录里创建setup.py#-*-coding:utf-8-*-#author:navysummer#email:navysummer@yeah.netimportshutilimportsetuptoolsfromsetuptools.command.......
  • python字符串常用方法介绍,基于python3.10
     python字符串常用方法-目录:1、strip()、lstrip()、rstrip()2、removeprefix()、removesuffix()3、replace()4、split()、rsplit()5、join()6、upper()、lower()、capita......
  • Python——pygam库实现弹跳小球
    代码实现:importsys#导入sys模块importpygame#导入pygame模块pygame.init()#初始化pygamesize=width,height=700,500#设置窗口screen......
  • 优雅简单玩转python3异步并发
    在python3之后,随着async/await引入,异步调用以全新而便捷的方式让人眼前一亮。首先,尽量用async/await定义协程这里以使用aiohttp请求网络,async函数中,不要使用blockingio......