第十七章 作用域
2017-03-29 20:52 szn好色仙人 阅读(110) 评论(0) 编辑 收藏 举报#1:变量可以在3个不同的地方分配,分别对应着3种不同的作用域: #A:如果变量在def内赋值,它被定位在这个函数之内 #B:如果一个变量在一个嵌套的def中赋值,对于嵌套的函数来说,它是非本地的 #C:如果在def之外赋值,它就是全局的 #D:python中的变量查找顺序是:本地作用域->上一层def或lambda的本地作用域->全局作用域->内置作用域 #2. #内置作用域通过一个名为__builtin__的标准库模块实现,前一半是内置的异常,后一半是内置函数 import builtins str = dir(builtins) #str = ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError',... #3. #A:global是一个命名空间声明,告诉python生成一个全局变量名,一般来说慎用global #B:可以通过import来导入另一个文件的全局变量,但是最好别去修改,在文件间通信的最好方法是通过调用函数,传递参数然后获得返回值 y = 10 def Fun(): global X global y y = 20 X = 10 #global x = 10 #编译错误 Fun() value = X #value = 10,若没有调用Fun()会导致运行错误 value1 = y #value1 = 20 #4. def Fun0(): L0 = [1, 2, 3] def Fun1(): #能记住嵌套作用域的变量的函数,尽管那个作用域可能已经不存在了 L0.append('a') return L0 return Fun1 value = Fun0() #value = <function Fun0.<locals>.Fun1 at 0x000000000273F950> value1 = value() #value1 = [1, 2, 3, 'a'] #5. #A:在某一个函数内部调用一个之后才被定义的函数是可行的,只要第二个函数定义的运行实在第一个函数调用前就行,在def内部的代码直到这个函数运行时才被验证 def FunA(): return FunB() #若在调用FunA()时候,FunB没有被定义则运行出错 def FunB(): return 'B' value = FunA() #value = 'B' #6. #A:lambda 表达式:由于嵌套作用域查找,lambda能够使用在上层函数作用域中的所有可用变量 def FunT(): value = 10 action = lambda n: value ** n return action value = FunT()(2) #value = 100 #7. #A:如果lambda或者def在函数中定义,嵌套在一个循环之中,并且嵌套的函数引用了一个上层作用域的变量,该变量被循环所改变,所有在这个循环中产生的函数将会有相同的值,即最后一次循环中完成时候被引用变量的值 #B:因为嵌套作用域中的变量在嵌套函数被调用时候才进行查找,所以他们实际上记住的是同一个值,为了让如下的代码能正常进行工作,必须使用默认参数把当前值传递给嵌套作用域的变量,因为默认参数是在嵌套函数创建时候评估而非调用时候评估 def FunA(): L0 = [] for i in range(1, 3): L0.append(lambda : i ** 2) return L0 value = FunA() #value = [<function FunA.<loca...00290F9D8>, <function FunA.<loca...00290FB70>] v0 = value[0]() #v0 = 4 v1 = value[1]() #v1 = 4 def FunA(): L0 = [] for i in range(1, 3): L0.append(lambda : i ** 2) i = 10 return L0 value0 = FunA()[0]() #value0 = 100 value1 = FunA()[1]() #value1 = 100 def FunA(): L0 = [] for i in range(1, 3): L0.append(lambda i = i: i ** 2) i = 10 return L0 value0 = FunA()[0]() #value0 = 1 value1 = FunA()[1]() #value1 = 4 #8. #A:在函数中,可以引用外部作用域的变量,但是不能让这个变量去引用别的值,当使用了global时就可以达到这个目的 L0 = [] def Fun(): L1 = L0 L1.append(10) L1 = 1 Fun() #L0 = [10] def Fun(): global L0 L0.append(10) L0 = 1 Fun() #L0 = 1 #9. #默认情况下,不允许修改嵌套的def作用域中的名称,使用nonlocal可以达到这个目的 #nonlocal和global一样,声明了将要在一个嵌套的作用域中修改的名称,和global不同的是,nonlocal应用于一个嵌套的函数作用域中的名称而不是所有def之外的全局模块作用域 #而且在声明nonlocal的时候,他必须已经存在于该嵌套函数的外部函数的作用域中,nonlocal实现了把一个名称的查找限制在嵌套的def中 #global声明变量的时候,变量可以不存在,但是在后续的使用时,必须先定义该变量 def Fun(): value = 0 def FunA(): try: value += 1 except: pass #调用FunA的时候会运行至此 return FunA F0 = Fun() F0() def Fun(): value = 0 def FunA(): nonlocal value value += 1 return value return FunA F0 = Fun() value = F0() #value = 1 value = F0() #value = 2 F1 = Fun() value = F1() #value = 1 F0 = None F0 = Fun() value = F0() #value = 1 value = F1() #value = 2 def Fun0(): value = 0 def FunA(): def FunB(): nonlocal value value += 1 return value return FunB return FunA value = Fun0()()() #value = 1 value = Fun0()()() #value = 1 pFun = Fun0() value = pFun()() #value = 1 value = pFun()() #value = 2 def Fun1(): global Fun1Value #将Fun1Value加入到全局作用域中 Fun1Value = 10 #由于Fun1Value没有在Fun1外部定义,所以在使用Fun1Value前必须先进行定义,否则会发生错误 Fun1Value += 1 return Fun1Value value = Fun1() #value = 11 value = Fun1Value #value = 11 Fun1Value = 11 def Fun2(): global Fun2Value try: Fun2Value += 1 except: Fun2Value = 0 Fun2() #Fun2Value = 0 Fun2() #Fun2Value = 1 Fun2() #Fun2Value = 2