Python局部变量与全局变量

在一个异步任务中,我想开一个全局变量,用来累计失败次数,当失败次数达到20时清空重置,程序阻塞10分钟。

  1. 本来想这么写
failnum = 0
def dealfail():
    failnum = failnum + 1
    if failnum >= 3:
        failnum = 0

for i in range(10):
    dealfail()
    print(failnum)

UnboundLocalError: local variable 'failnum' referenced before assignment

竟然运行不了,报错 函数dealfail 中没用初始化 变量failnum

  1. 函数dealfail没有出现 在等号左边failnum 时,函数dealfail 可对全局变量failnum 进行读操作
failnum = 0
def dealfail():
    print(failnum)
    print("="*10)

dealfail()

0

==========

  1. 但当 函数dealfail 出现了位于等号左边的 failnum 时,即使作为解释性语言,连"========"也打印不出来就直接报错:
failnum = 0
def dealfail():
    print(failnum)
    print("="*10)
    failnum = failnum + 1

dealfail()

UnboundLocalError: local variable 'failnum' referenced before assignment

  1. 但与此同时,如果是其他的一些错误,"========"又是可以被打印出来的:
failnum = 0
def dealfail():
    print(failnum)
    print("="*10)
    b = 1/0

dealfail()

0

==========

ZeroDivisionError: division by zero

我是这样想的,不使用global修饰的情况下,如果一个变量在函数中被定义(修改),即使定义(修改)操作在读操作的条件顺序之后,读操作所引用的变量也会是局部变量,Python在函数执行之前会对函数中所有变量的指向进行内存分配,局部优先级高于全局。

想用全局的failnum需要用global来声明。如此初步实现了需求。

failnum = 0
def dealfail():
    global failnum 
    failnum = failnum + 1
    if failnum >= 3:
        failnum = 0

for i in range(10):
    dealfail()
    print(failnum)

大道至简,知易行难。如果上学时对全局变量、局部变量,乃至栈区、堆区、内存分配有一定了解,这个问题可以触类旁通。想起之前面试时被问的:C语言中static关键字的作用。关于这个问题,https://blog.csdn.net/u012197749/article/details/83187841 这篇文章写的很详细。

依照现在的理解:C语言在编译运行时会分配产生三个内存池

  1. 栈区 HEAP

    1. 由编译器自动分配和释放,用于存储函数的参数值、局部变量等

    2. 实现类似数据结构中的栈

    3. 栈的优点:

      1. 自动分配释放,速度较快
    4. 栈的缺点:

      1. 爆栈:当数据过多或者函数递归层数过深时
  2. 堆区 STACK

    1. 动态分配的内存区域,由程序运行时分配和释放

    2. 实现类似数据结构中的链表

    3. 堆的优点:

      1. 可动态扩容,大小不固定
    4. 堆的缺点:

      1. 内存泄漏:定义没释放
      2. 内存碎片:分配回收时不连续的内存需要整理
      3. 线程共享:同进程下线程都可访问
  3. 静态区

    1. 用于存储静态变量和常量,在程序执行前分配,执行结束后释放

问题:(C/C++中)

  1. 定义一个vector<int> a(100);和一个array<int,100> a;则其中a和[100]分别在哪个内存池?

  2. 一个类中的静态成员变量存放在哪个内存池?

  3. 一个函数中的static修饰的变量,存放在哪个内存池?

posted @ 2023-06-27 23:52  anyiya  阅读(34)  评论(0编辑  收藏  举报