命名空间的概念的提出是为了划分和控制变量是否可见,以及生存周期的长短;命名空间的作用范围叫做作用域。
划分一块区域保存所有数据,以字典的方式存储(变量与值形成映射关系)。一共三种。
局部变量就是在函数内部定义的变量,局部变量所在的就是局部命名空间,作用域仅仅在函数内部可见,也就是说只能在函数内部使用。
# 在函数中创建的变量就是局部变量
def func():
var = '局部变量'
# 局部变量不可以在非对应局部环境中使用
print(var) # error, 该变量不存在
全局变量就是在函数外部定义的或者使用global在函数内部定义的变量,全局变量所在的命名空间就是全局命名空间,作用域横跨整个文件,就是说在整个文件中的任何一个地方都可以使用全局变量。
# 在全局环境中创建的变量就是全局变量
var = '全局变量'
def func():
# 在局部中也可以使用全局变量
print(var) # 全局变量
func()
局部变量最好不要和全局变量同名,如果同名,在局部环境中就无法使用全局变量了。
var = '全局变量'
def func():
# 先使用了全局变量
print(var) # error, 找不到该变量
# 然后局部变量和全局变量同名,那么新的局部变量就会在局部空间中覆盖了全局变量的一切影响力,这就叫做局部变量修改了全局变量;
# 这样的话导致在局部空间中无法在使用该全局变量,之前在局部空间中使用的该变量就成为了先调用后定义;导致出错。
var = '局部变量'
print(var)
func()
# 但是局部同名变量不会影响到全局变量的值
print(var) # 全局变量
内置函数就是内建命名空间,指的是那些python中自带的、内置的函数。
局部变量作用域:在函数的内部
全局变量作用域:横跨整个文件
内置变量 -> 全局变量 -> 局部变量
内置变量自python程序运行的时候开始,一直等到python程序结束之后才会释放;
全局变量自创建开始,一直到程序结束或者被清除才会释放;
局部变量字创建开始,一直到局部空间执行结束或者清除就会释放;
| 函数 | 作用 |
|---|---|
| globals() | 存放着全局作用域中的所有内容,以字典的形式返回 |
| locals() | 存放着当前作用域中的所有内容,以字典的形式返回 |
返回所有的全局作用域中的内容。
如果在全局,调用globals之后,获取的是打印之前的所有变量,返回字典,全局空间作用域;
# 定义一些全局变量
a, b, c = 1, 2, 3
# 调用globals函数
res = globals()
# 第一次打印,包含a b c
print(res)
'''
结果:
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000002DBDCA5D198>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/0-project/python/mymsr/ceshi/test6.py', '__cached__': None, 'a': 1, 'b': 2, 'c': 3, 'res': {...}}
'''
# 再定义一些变量
d, e, f = 1, 2, 3
# 第二次打印,包含a b c d e f
print(res)
'''
结果:
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000002DBDCA5D198>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/0-project/python/mymsr/ceshi/test6.py', '__cached__': None, 'a': 1, 'b': 2, 'c': 3, 'res': {...}, 'd': 1, 'e': 2, 'f': 3}
'''
如果在局部,调用globals之后,获取的是调用之前的所用变量,返回字典,全局空间作用域;
# 定义一些全局变量
a, b, c = 1, 2, 3
# 在局部环境中使用globals函数
def func():
res = globals()
print(res)
# 调用函数
func()
'''
结果:不包含 d e f
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001E7C287D198>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/0-project/python/mymsr/ceshi/test6.py', '__cached__': None, 'a': 1, 'b': 2, 'c': 3, 'func': <function func at 0x000001E7C2772F28>}
'''
# 再定义一些全局变量
d, e, f = 4, 5, 6
# 第二次调用函数
func()
'''
结果:包含 d e f
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000021A3F3DD198>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/0-project/python/mymsr/ceshi/test6.py', '__cached__': None, 'a': 1, 'b': 2, 'c': 3, 'func': <function func at 0x0000021A3F2D2F28>, 'd': 4, 'e': 5, 'f': 6}
'''
globals可以动态创建全局变量
dic = globals()
print(dic) # 返回系统的字典
'''
结果:
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000026F357ED198>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/0-project/python/mymsr/ceshi/test6.py', '__cached__': None, 'dic': {...}}
'''
# 在全局的字典当中,通过添加键值对,自动创建全局变量,对应的键是变量名,对应的值是变量指向的值
dic['msr123123123'] = '123456'
print(msr123123123) # 123456
# 查看全局内容
print(dic)
'''
结果:
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000161D944D198>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/0-project/python/mymsr/ceshi/test6.py', '__cached__': None, 'dic': {...}, 'msr123123123': '123456'}
'''
返回当前所在作用域的所有内容。
如果在全局,调用locals之后,获取的是打印之前的所有变量,返回字典,全局空间作用域;
# 定义一些全局变量
a, b, c = 1, 2, 3
# 调用locals函数
res = locals()
# 第一次打印,包含a b c
print(res)
'''
结果:
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000018C82A3D198>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/0-project/python/mymsr/ceshi/test1.py', '__cached__': None, 'a': 1, 'b': 2, 'c': 3, 'res': {...}}
'''
# 再定义一些变量
d, e, f = 1, 2, 3
# 第二次打印,包含a b c d e f
print(res)
'''
结果:
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000018C82A3D198>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/0-project/python/mymsr/ceshi/test1.py', '__cached__': None, 'a': 1, 'b': 2, 'c': 3, 'res': {...}, 'd': 1, 'e': 2, 'f': 3}
'''
如果在局部,调用locals之后,获取的是调用之前的所有变量,返回字典,局部空间作用域;
# 定义一些局部变量
def func():
# 局部变量
aa, bb, cc = 11, 22, 33
# 第一遍调用
res = locals()
# 第一次打印,包含 aa bb cc
print(res) # {'cc': 33, 'bb': 22, 'aa': 11}
# 再定义一些局部变量
dd, ee, ff = 44, 55, 66
# 第二次打印,不包含 dd ee ff
print(res) # {'cc': 33, 'bb': 22, 'aa': 11}
# 调用第二遍
res2 = locals()
# 打印第一次的调用,包含 dd ee ff
print(res) # {'cc': 33, 'bb': 22, 'aa': 11, 'ff': 66, 'ee': 55, 'dd': 44, 'res': {...}}
# 打印第二次的调用,包含 dd ee ff
print(res2) # {'cc': 33, 'bb': 22, 'aa': 11, 'ff': 66, 'ee': 55, 'dd': 44, 'res': {...}}
# 调用函数,返回在函数中的局部变量
func()
| 关键字 | 作用 |
|---|---|
| global | 声明全局变量、获取使用和修改全局变量的权限 |
| nonlocal | 修改局部变量(当前函数的上一层的局部变量) |
在局部环境中创建的变量是局部变量,在全局环境中是不可以使用的。但是使用global定义的变量就是一个全局变量,这个变量可以全局环境中使用。
def func():
var = '局部变量'
global glvar
glvar = '全局变量'
# 一定要执行局部环境哟
func()
# 全局环境中
print(var) # error,局部变量不能调用
# 使用global定义的变量是全局变量
print(glvar) # 全局变量
在局部环境中无法修改全局变量的值,使用global可以在局部环境中修改全局变量。
var = '全局变量'
def func():
global var
var = '局部环境中修改'
func()
print(var) # 局部环境中修改
在学习nonlocal之前我们需要先学习一些关于函数嵌套的知识。
函数之间是可以互相嵌套的,外层的叫做外函数,内层的叫做内函数。
def outer():
print('我叫outer,是外函数')
def inner():
print('我叫inner,在outer的里面,是内函数')
# 在外函数中执行内函数
inner()
# 执行外函数
outer()
'''
结果:
我叫outer,是外函数
我叫inner,在outer的里面,是内函数
'''
# 外层是outer,内层是inner,最里层是smaller,调用smaller里的所有代码
def outer():
print('我叫outer,是最外层函数,是inner和smaller的外函数')
def inner():
print('我叫inner,是outer的内函数,是smaller的外函数')
def smaller():
print('我叫smaller,是outer和inner的内函数')
# 先在inner中执行smaller
smaller()
# 然后在outer中执行inner
inner()
# 最后再执行outer才能执行smaller函数
outer()
'''
结果:
我叫outer,是最外层函数,是inner和smaller的外函数
我叫inner,是outer的内函数,是smaller的外函数
我叫smaller,是outer和inner的内函数
'''
我们在多个函数嵌套的时候要注意,不管外函数还是内函数,都是函数,只要是函数中的变量都是局部变量。
内涵可以使用外函数的局部变量,外函数不能直接使用内函数的局部变量。
LEGB原则就是一个就近找变量原则,依据就近原则,从下往上,从里向外,依次寻找。
B————Builtin(Python):Python内置模块的命名空间 (内建作用域)
G————Global(module):函数外部所在的命名空间 (全局作用域)
E————Enclosing Function Locals:外部嵌套函数的作用域(嵌套作用域)
L————Local(Function):当前函数内的作用域 (局部作用域)

现在我们正式学习nonlocal关键字,nonlocal的作用是修改当前局部环境中上一层的局部变量。那么我们根据这个作用便知道了nonlocal的使用环境至少是一个二级的嵌套环境,且外层的局部环境中必须存在一个局部变量。
def outer():
# 定义变量
lvar = 'outer var'
def inner():
# 内函数使用nonlocal修改上一层的局部变量
nonlocal lvar
lvar = 'inner var'
# 执行inner函数
inner()
print(lvar)
outer() # inner var
假如上一层的局部环境中没有这个变量怎么办,那么就根据LEGB原则向上寻找。
def outer():
# 定义变量
lvar = 'outer var'
def inner():
def smaller():
# smaller中修改变量,但是inner中没有,就向上寻找修改outer中的变量
nonlocal lvar
lvar = 'smaller var'
# 执行 smaller函数
smaller()
# 执行inner函数
inner()
print(lvar)
# 执行outer函数
outer()
如果层层寻找,直到最外层的函数中也没有这个变量,那么就会报错,因为nonlocal只会修改局部变量,如果超出范围,就会报错。
var = 1 # 变量在最外层的函数之外,也就是全局变量,nonlocal无法修改
def outer():
def inner():
def smaller():
nonlocal var # error,没有局部变量
var = 2
print(var)
smaller()
inner()
outer()
局部环境中可以调用全局变量,但是不能修改(但是如果全局变量是可变数据则可以修改其中的值)
全局环境中不能调用局部变量 也不能修改
(在函数内部使用,可以对全局变量进行操作)
1、可以在局部环境中定义全局变量
2、可以在局部环境中修改全局变量
(在内函数中使用,可以在内函数中修改外函数中的局部变量)
1、locals获取当前作用域当中所有的变量
如果在全局调用locals之后,获取的是打印之前的所有变量,返回字典,全局作用域
如果在局部调用loclas之后,获取的是调用之前的所有变量,返回字典,局部作用域
2、globals只获取全局空间中的所有变量
如果在全局调用globals之后,获取的是打印之前的所用变量,返回字典,全局作用域
如果在局部调用globals之后,获取的是调用之前的所用变量,返回字典,全局作用域
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的
我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty