Python tricks(2) -- method默认参数和闭包closure
Python的method可以设置默认参数, 默认参数如果是可变的类型, 比如list, map等, 将会影响所有的该方法调用.
下面是一个简单的例子
1
2
3
4
5
6
7
8
9
10
11
12 |
def
f(a = None , l = []): if
not
a: return
l l.append(a) return
l if
__name__ = =
"__main__" : print
f( "a" ) print
f( "b" ) print
f( "b" ) print
f(l = []) print
f() |
输出结果如下:
1
2
3
4
5 |
[ ‘a‘ ] [ ‘a‘ , ‘b‘ ] [ ‘a‘ , ‘b‘ , ‘b‘ ] [] [ ‘a‘ , ‘b‘ , ‘b‘ ] |
我们可以看到f的默认参数l在所有的方法调用中都受到影响了, 这个可能并不一定符合默认参数设置的初衷.
想要避免这种影响, 可以这样做.
1
2
3
4
5
6
7
8
9
10
11
12
13
14 |
def
f(a = None , l = None ): if
not
l: l =
[] if
not
a: return
l l.append(a) return
l if
__name__ = =
"__main__" : print
f( "a" ) print
f( "b" ) print
f( "b" ) print
f(l = []) print
f() |
将l设置为None, 在方法内部判断, 并初始化为空, 这样改变后的输出为:
1
2
3
4
5 |
[ ‘a‘ ] [ ‘b‘ ] [ ‘b‘ ] [] [] |
具体可以查阅官方文档的说明[参考1].
下面再来说说闭包.
我个人理解, 闭包的形式是方法的嵌套, 主要的作用是为了在整个调用过程中保存方法的某些状态. 有些时候method的默认参数也可以做到保存方法状态.
用dict保存一些变量信息, 类似context的东西.
闭包实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 |
def
context(): data =
{} def
_context(key, value = None ): if
value: data[key] =
value return
data else : return
data.get(key, None ), data return
_context c =
context() print
c( "key" ) print
c( "key" , "value" ) print
c( "key" ) |
方法默认参数的实现
1
2
3
4
5
6
7
8
9
10 |
def
d(key, value = None , data = {}): if
value: data[key] =
value return
data else : return
data.get(key, None ), data print
d( "key" ) print
d( "key" , "value" ) print
d( "key" ) |
通过实现类的magic method来实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 |
class
e( object ): def
__init__( self ): self .data =
{} def
__call__( self , key, value = None ): if
value: self .data[key] =
value return
self .data else : return
self .data.get(key, None ), self .data f =
e() print
f( "key" ) print
f( "key" , "value" ) print
f( "key" ) |
三种实现的输出结果都是一样的
1
2
3 |
( None , {}) { ‘key‘ : ‘value‘ } ( ‘value‘ , { ‘key‘ : ‘value‘ }) |
在python中方法本身也是一个对象, 可以有自己的属性等, 通过第三种实现, 我们可以理解默认参数是方法对象的一个属性, 伴随其生命周期.
使用def func()定义的时候就是定义了一个方法的类, 之后获取了一个名为func的实例化对象.
可能有人会奇怪, 这种东西哪里有使用的场景了? 我能想到的一个场景就是, 我想通过查找字典的方式获取一个信息, 这个字典是一个大文件(加载耗时), 我只希望加载一次, 这个时候闭包可以发挥其特殊的作用, 而且代码也比较优雅.
本文是笔者对于python方法的一些理解. 水平有限, 欢迎拍砖!
参考文档:
- Python Docs: http://docs.python.org/2/tutorial/controlflow.html#default-argument-values
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。