Python中的变量名在第一次被赋值时已经创建, 并且必须经过赋值后才能够使用.
每一个模块都是一个全局作用域, 没有类型C++那样的能够存活在整个项目中的作用域.Python作用域的范围仅限于单个文件(模块).赋值的变量名除非声明为全局变量(通过global), 否则均为本地变量.所有的变量名都可以归纳为本地, 全局或者内置.注意实地改变变量并不会把变量划分为本地变量, 实际上只有对变量名赋值才可以.
变量名解析: LEGB原则
变量名分为三个作用域进行查找, 本地 => 函数内 => 全局 => 内置
全局声明将赋值变量名映射到模块文件内部的作用域(全局域).
对于内置名字, 如zip函数, 可以直接使用, 如zip(), 或者import __building__; __buildin__.zip()
自定义变量会掩盖自带的名字, 甚至可以替换自带的名字, 如__buildin__.zip = …
通过global将变量声明为全局域变量
X = 88 def func(): global X X = 99 //(改变全局域的X)
除了通过global方式访问全局域变量外, 还可以在函数中import自身module, 然后通过模块名.变量的形式访问.
// thismod.py var = 99 def local(): var = 0 def glob1(): global var var += 1 def glob2(): var = 0 import thismod thismod.var += 1 def glob3(): var = 0 import sys glob = sys.module['thismod'] glob.var += 1
工厂函数
def maker(N): def action(X): return X**N return action func = maker(2) f(3) == 9
使用默认参数来保留嵌套作用域的状态
def maker():
x = 88
def action(x = x):
print x
return action
func = maker()
f(3) // print 88
在某一个函数内部调用一个之后才定义的函数是可行的, 只要第二个函数定义是在第一个函数调用之前就行.
lamda表达式:
action = (lambda n,x: return x ** n); action(2,3) == 9 def makeActions(): acts = [] for i in range(5): acts.append(lambda x: i ** x) return acts acts = makeActions() acts[2](3) == 64 // 因为嵌套作用域中的变量在嵌套的函数被调用时才进行查找, 所以这里的acts函数组里的每个i都是4 def makeActions(): acts = [] for i in range(5): acts.append(lambda x, i = i : i ** x) return acts acts = makeActions() acts[2](3) == 8// 在lambda中, 用默认参数的方式记住每一次i迭代的值.
作为参数被传递的对象从来不自动拷贝. 不可变参数通过值传递, 可变对象是通过引用进行传递. 自动对传入的参数进行赋值的效果与运行一系列简单的赋值语句是相同的.
返回多个变量: def return(x, y); return2(1,2) == (1,2) 看似返回多个, 实际上返回的是一个元组
函数参数匹配表
语法 位置 解释
func(value) 调用者 常规参数:通过位置进行匹配 func(name = value) 调用者 关键字参数: 通过变量名匹配 func(*name) 调用者 以name传递所有的对象, 并作为独立的基于位置的参数 func(**name) 调用者 以name传递所有关键字/值, 并作为独立的关键字参数 def func(name) 函数 常规参数:通过位置进行匹配 def func(name = value) 函数 默认参数值, 如果没有在调用中传递 def func(*name) 函数 匹配并收集(在元组中)所有包含位置的参数 def func(**name) 函数 匹配并收集(在字典中)所有包含关键字的参数 // L1, L5 def func(a,b,c):print a,b,c func(1,2,3) // L2, L6 def func(a,b,c):print a,b,c func(1,b = 2, c = 3) // L3, L7 def func(a,b,c):print a,b,c args = (1,2,3) func(*args) // L4, L8 def func(a,b,c):print a,b,c args = {'a':1, 'b' : 2, 'c' : 3} func(**args) Python函数可作为传输传递 def minmax(test, *args): res = args[0] for arg in args[1:]: if test(arg, res): res = arg return res def lessthan(x,y): return x < y def grtrthan(x,y): return x > y print minmax(lessthan, 4,1,2,3) print minmax(grtrthan, 4,1,2,3)
参数匹配法则
在函数调用中, 所有的非关键字参数必须首先出现, 其后跟随所有的关键字参数, 后面跟着*name的形式, 并且如果需要的话, 最后是**name的形式
在函数头部, 参数必须以相同的顺序出现: 一般参数, 默认参数, 后面是*name和**name.