究竟是什么*args和**kwargs意味着什么呢?
根据Python文档,从它看来,它传递了一个参数元组.
def foo(hello, *args):
print hello
for each in args:
print each
if __name__ == '__main__':
foo("LOVE", ["lol", "lololol"])
Run Code Online (Sandbox Code Playgroud)
打印出:
LOVE
['lol', 'lololol']
Run Code Online (Sandbox Code Playgroud)
你如何有效地使用它们?
Pau*_*ite 252
在函数定义的参数列表中放置*args和/或**kwargs作为最后一项允许该函数接受任意数量的参数和/或关键字参数.
例如,如果你想编写一个函数来返回所有参数的总和,无论你提供了多少,你都可以像这样写:
def my_sum(*args):
return sum(args)
Run Code Online (Sandbox Code Playgroud)
当你覆盖一个函数时,它可能更常用于面向对象的编程,并希望用用户传入的任何参数调用原始函数.
你实际上并没有给他们打电话args和kwargs,这只是一个惯例.这是*和**该做的魔力.
官方Python文档具有更深入的外观.
S.L*_*ott 90
此外,我们使用它们来管理继承.
class Super( object ):
def __init__( self, this, that ):
self.this = this
self.that = that
class Sub( Super ):
def __init__( self, myStuff, *args, **kw ):
super( Sub, self ).__init__( *args, **kw )
self.myStuff= myStuff
x= Super( 2.7, 3.1 )
y= Sub( "green", 7, 6 )
Run Code Online (Sandbox Code Playgroud)
这种方式Sub并不真正知道(或关心)超类初始化是什么.如果您意识到需要更改超类,您可以解决问题,而不必为每个子类中的细节烦恼.
ori*_*rip 67
注意S.Lott注释中很酷的东西- 你也可以使用*mylist和调用函数**mydict来解析位置和关键字参数:
def foo(a, b, c, d):
print a, b, c, d
l = [0, 1]
d = {"d":3, "c":2}
foo(*l, **d)
Run Code Online (Sandbox Code Playgroud)
将打印: 0 1 2 3
ori*_*rip 25
另一个很好用的*args和**kwargs:你可以定义通用的"catch all"函数,这对于返回这样一个包装器而不是原始函数的装饰器来说非常有用.
一个简单的缓存装饰器的例子:
import pickle, functools
def cache(f):
_cache = {}
def wrapper(*args, **kwargs):
key = pickle.dumps((args, kwargs))
if key not in _cache:
_cache[key] = f(*args, **kwargs) # call the wrapped function, save in cache
return _cache[key] # read value from cache
functools.update_wrapper(wrapper, f) # update wrapper's metadata
return wrapper
import time
@cache
def foo(n):
time.sleep(2)
return n*2
foo(10) # first call with parameter 10, sleeps
foo(10) # returns immediately
Run Code Online (Sandbox Code Playgroud)
Kau*_*ose 17
只是为了澄清如何解包参数,并处理缺少的参数等.
def func(**keyword_args):
#-->keyword_args is a dictionary
print 'func:'
print keyword_args
if keyword_args.has_key('b'): print keyword_args['b']
if keyword_args.has_key('c'): print keyword_args['c']
def func2(*positional_args):
#-->positional_args is a tuple
print 'func2:'
print positional_args
if len(positional_args) > 1:
print positional_args[1]
def func3(*positional_args, **keyword_args):
#It is an error to switch the order ie. def func3(**keyword_args, *positional_args):
print 'func3:'
print positional_args
print keyword_args
func(a='apple',b='banana')
func(c='candle')
func2('apple','banana')#It is an error to do func2(a='apple',b='banana')
func3('apple','banana',a='apple',b='banana')
func3('apple',b='banana')#It is an error to do func3(b='banana','apple')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
147170 次 |
| 最近记录: |