Python局部变量与全局变量
在一个异步任务中,我想开一个全局变量,用来累计失败次数,当失败次数达到20时清空重置,程序阻塞10分钟。
- 本来想这么写
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。
- 在 函数dealfail 中没有出现 在等号左边 的 failnum 时,函数dealfail 可对全局变量failnum 进行读操作
failnum = 0
def dealfail():
print(failnum)
print("="*10)
dealfail()
0
==========
- 但当 函数dealfail 出现了位于等号左边的 failnum 时,即使作为解释性语言,连"========"也打印不出来就直接报错:
failnum = 0
def dealfail():
print(failnum)
print("="*10)
failnum = failnum + 1
dealfail()
UnboundLocalError: local variable 'failnum' referenced before assignment
- 但与此同时,如果是其他的一些错误,"========"又是可以被打印出来的:
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语言在编译运行时会分配产生三个内存池
-
栈区 HEAP:
-
由编译器自动分配和释放,用于存储函数的参数值、局部变量等
-
实现类似数据结构中的栈
-
栈的优点:
- 自动分配释放,速度较快
-
栈的缺点:
- 爆栈:当数据过多或者函数递归层数过深时
-
-
堆区 STACK:
-
动态分配的内存区域,由程序运行时分配和释放
-
实现类似数据结构中的链表
-
堆的优点:
- 可动态扩容,大小不固定
-
堆的缺点:
- 内存泄漏:定义没释放
- 内存碎片:分配回收时不连续的内存需要整理
- 线程共享:同进程下线程都可访问
-
-
静态区:
- 用于存储静态变量和常量,在程序执行前分配,执行结束后释放
问题:(C/C++中)
-
定义一个vector<int> a(100);和一个array<int,100> a;则其中a和[100]分别在哪个内存池?
-
一个类中的静态成员变量存放在哪个内存池?
-
一个函数中的static修饰的变量,存放在哪个内存池?