全局变量 静态变量 局部变量 啥时候创建 啥时候撤销
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了全局变量 静态变量 局部变量 啥时候创建 啥时候撤销相关的知识,希望对你有一定的参考价值。
这些都懂,面试的时候我也说这些,人家不听,就是问什么时候创建 什么时候撤销
看题就知道没人回答,就我这个菜鸟随便说说吧内存里有:程序区,静态存储区,动态存储区
可执行程序代码使用程序区
变量使用静态存储区,动态存储区
全局变量和局部变量放一起区别
自动类型变量auto,静态类型变量static,寄存器类型变量register,外部类型变量extern放一起区别
===========================================================================
全局变量和局部变量:
块作用域 (局部变量)
文件作用域 (全局变量)
函数原型作用域 (局部变量)
函数作用域 (局部变量)
类作用域
---------------------------------------------------------------------------
变量说明在前,使用在后
块内说明的变量i是局部变量,块作用域有效,块结束,变量消失
函数内说明的变量i是局部变量,函数结束,变量消失
局部变量i在作用域内屏蔽其余同名变量i,局部优先,可以用::i访问全局变量i
for说明的循环控制变量i在for循环结束后仍然有效,for所在的块结束时才消失
函数外说明的变量i是全局变量,文件作用域有效
函数内extern说明的变量i是全局变量,文件作用域有效
函数原型说明()内的参数变量i的作用域是属函数原型作用域,很小很小的局部变量
函数原型作用域变量i等只作用于函数原型说明的()内
函数原型作用域变量i等很小很小的局部变量可以省去,只留下参数类型说明
函数原型作用域变量与函数定义,函数调用无关
函数定义()内的参数变量i以及函数定义内部说明的变量i是局部变量,函数作用域有效
函数定义内的标号label只在本函数作用域有效,其余任何地方都goto不到
===========================================================================
自动类型变量
auto 修饰
一定是局部变量
使用动态存储区
---------------------------------------------------------------------------
静态类型变量
static 修饰
使用静态存储区
静态类型局部变量主要用于保存函数运行结果,以便下次继续使用
不论是否在它作用域内,它始终占着存储空间,未附初值,会自动给默认初值0
不在它的作用域内,通过它的地址来访问静态类型局部变量的值
静态类型全局变量说明变量只作用域这个源程序文件
一个程序只由一个文件组成时,static可有可无
一个程序只由多个文件组成时,static解决多文件中全局变量重名问题
---------------------------------------------------------------------------
寄存器类型变量
register 修饰
一定是动态局部变量
主要用于控制循环次数的临时变量
---------------------------------------------------------------------------
外部类型变量
extern 修饰
以上全部是自己整理手打字的,全是基础啊概念
理解了以上在多多练习,一定要多多练习,就能什么理解变量了 参考技术A 静态变量属于类,不用实例化就已经存在,所有的实例共享同一个静态变量,可以通过类名和实例名来访问。实例变量属于实例,每个实例都有自己的这个变量,只能通过实例名来访问。再有就是静态变量可以通过类名.方法名可以点出来。而实例变量需要先实例化那个类才可以得到 参考技术B 静态变量是按生命周期大小分的
全局 ,局部是按 作用域分的
全局变量,静态局部变量,静态全局变量都在静态存储区分配空间,即编译的时候已经决定好了,而局部变量在栈里分配空间
全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误
局部变量在调用函数时分配,函数结束时释放资源,
全局和静态变量在整个函数结束后,释放内存资源。
python啥时候删除变量?
【中文标题】python啥时候删除变量?【英文标题】:when does python delete variables?python什么时候删除变量? 【发布时间】:2014-08-13 12:28:28 【问题描述】:我知道 python 有一个自动垃圾收集器,所以它应该在不再引用变量时自动删除变量。
我的印象是局部变量(函数内部)不会发生这种情况。
def funz(z):
x = f(z) # x is a np.array and contains a lot of data
x0 = x[0]
y = f(z + 1) # y is a np.array and contains a lot of data
y0 = y[0]
# is x and y still available here?
return y0, x0
del x
是节省内存的正确方法吗?
def funz(z):
x = f(z) # x is a np.array and contains a lot of data
x0 = x[0]
del x
y = f(z + 1) # y is a np.array and contains a lot of data
y0 = y[0]
del y
return y0, x0
编辑:我已经编辑了我的示例,使其更类似于我的实际问题。
在我的真正问题中,x 和 y 不是列表,而是包含不同大 np.array
的类。
编辑:我能够运行代码:
x = f(z)
x0 = x[0]
print(x0)
y = f(z + 1)
y0 = [0]
print(y0)
【问题讨论】:
我的印象是局部变量(函数内部)不会发生这种情况。 是什么让您有这种印象?函数结束时清除本地名称;当它们的引用计数降至 0 时,它们引用的对象将被删除就像 Python 中的其他任何地方。 我有一个函数可以运行一些独立的脚本。我收到内存不足错误。我知道我能够独立运行这些脚本 @Donbeo:当函数运行脚本时,你是如何运行它们的?它们是作为单独的进程还是作为模块运行? @MartijnPieters OP 可能会因为 python 中的“范围”与许多其他语言中的“范围”不同而感到困惑。例如,for
循环没有定义新的作用域,并且它的变量在最后一次迭代后仍然有效。
【参考方案1】:
实现使用引用计数来确定何时应该删除变量。
在变量超出范围后(如您的示例),如果没有剩余的引用,那么内存将被释放。
def a():
x = 5 # x is within scope while the function is being executed
print x
a()
# x is now out of scope, has no references and can now be deleted
除了列表中的字典键和元素之外,通常很少有理由在 Python 中手动删除变量。
不过,正如this question 的回答中所说,使用 del 可以用于显示意图。
【讨论】:
重要提示:垃圾收集和引用计数不是一回事,Python 两者兼而有之。然而,垃圾收集主要用于清理循环引用,因此不是内存管理的主要形式。引用计数会在引用计数降至零时立即释放内存,它不会等待 GC 周期。当然也有一些例外,因为 python 会缓存整数和短字符串,即使出于性能原因没有对它们的实时引用。【参考方案2】:将两个概念分开很重要:名称和值。 Python 中的变量是指一个值的名称。名称有作用域:当你定义一个局部变量时(通过给一个名字赋值),这个变量的作用域就是当前函数。当函数返回时,变量消失。但这并不意味着价值消失了。
值没有作用域:它们一直存在,直到没有更多名称引用它们为止。您可以在函数中创建一个值,然后从该函数返回它,使函数外部的名称引用该值,并且该值将不会被回收,直到将来所有对它的引用都消失了。
更多细节(包括图片!)在这里:Facts and Myths about Python Names and Values。
【讨论】:
【参考方案3】:在单独的函数中写下你想从内存中清除的东西。在您的示例中,您可以这样做
def xdef(z):
x = f(z) # x is a np.array and contains a lot of data
x0 = x[0]
def funz(z):
xdef(z)
y = f(z + 1) # y is a np.array and contains a lot of data
y0 = y[0]
return y[0], x[0]
这会导致异常
【讨论】:
【参考方案4】:这取决于实现和变量的类型。对于像 int 这样的简单对象,有一些优化。例如,在 CPython 中,一个简单的 int 将重用相同的内存,即使在使用了 del
之后也是如此。你不能指望这一点,但它确实说明事情比看起来更复杂。
请记住,当您del
时,您删除的是名称,不一定是对象。
例如:
# x is a np.array and contains a lot of data
更准确的措辞是:
# x references a np.array which contains a lot of data
del
将减少该对象的引用计数,但即使它降至零,也不能保证很快就会被垃圾回收。
建议您查看the gc
module 以获得解释和灵感。然后再想一想。
如果您“内存不足”,那么您的设计可能存在根本问题。很可能您一次加载了太多数据(尝试使用迭代器?),或者您的代码可能需要更好地结构化。
我刚刚看到你的编辑。您是否需要同时在内存中使用所有该数组?你能用发电机吗?
另一种选择是使用 SQLite 之类的数据库,或者 shelve
【讨论】:
是的,我需要所有的清单。这个例子不完全是我的代码。在我的代码中,f 返回一个类,其中该类中的某些元素很大 np.ndarray。如果我可以使用 del 之类的东西手动删除变量,那么我认为我的问题将得到解决以上是关于全局变量 静态变量 局部变量 啥时候创建 啥时候撤销的主要内容,如果未能解决你的问题,请参考以下文章