今天学习的是python编程中的关于作用域与参数的知识,下面是学习的总结:
1、变量名解析的LEGB原则:变量名引用分为三个作用域进行查找,本地作用域(L,每次调用函数时创建)、上一级调用的本地作用域(E)、全局作用域(G,模块作用域)、内置作用域(B,预定义的变量名如open)。仅对简单变量生效,对于特定对象的变量如object.spam,查找规则规则完全不同。内置作用域是一个名为__builtin__的内置模块,import后才可以使用,这时可以用dir(__buildin__)查看预定义的变量名。根据LEGB原则,在本地作用域定义一个新的open = 'spam'会导致open()函数不能被调用。global用于全局变量声明。
在模块导入时,导入其他模块的模块拥有了对其他模块变量的修改权,这使得被导入模块的维护变得复杂:维护者不知道第二个模块什么情况下会修改变量。因此最好的解决办法是不这样做,在文件间进行通信的最好办法就是通过调用函数,传递参数,然后获得返回值(用函数提供修改变量的接口,并且告诉维护者这个变量可以被其他模块改变)。
工厂函数(又称闭合),是能记住嵌套作用域的变量值的函数。示例:
>>> def maker(N): ... def action(X): ... return X ** N ... return action ... >>> f = maker(2) >>> f #显示f的引用>>> f(3) 9 >>> f(4) 16 >>> g = maker(3) >>> g(3) 27 >>> f(3) 9
2、对于函数参数,不可变参数是通过传值来传递,可变对象(列表、字典等)是通过传引用进行传递的。
多个返回值的常用return方式是使用元组。
函数参数的四种匹配方式:位置匹配、关键字参数、所有对象、所有关键字/值:
>>>def f(a,b,c):print a,b,c #常规匹配 >>>f(1,2,3) 1 2 3 >>>f(c=3,b=2,a=1) #关键字匹配 1 2 3 >>>f(1,c=3,b=2) #位置+关键字匹配 1 2 3 >>>def f(a,b=2,c=3):print a,b,c #默认参数 >>>f(1) 1 2 3 >>>f(a=1) 1 2 3 >>>def f(*args):print args # 任意参数* >>>f() () >>>f(1) (1,) >>>f(1,2,3,4) >>>def f(**args):print args # 任意参数**,把参数组装成为字典 >>>f() {} >>>f(a=1,b=2) {'a'=1,'b'=2}
相反地,调用函数在参数变量前面加*可以分解参数。参数匹配顺序:调用和定义中先是非关键字参数(name)、然后是关键字参数(name=value)、*name最后是**name。