Python 体中的扩展函数args
可能是个愚蠢的问题,但出于好奇 在python中,我可以在函数的签名中扩展*args和**kwargs def my_funcfoo,bar: printfoo={foo},bar={bar} 我的职责1,2 1 2 my_func1,bar=2 my_funcfoo=1,bar=2 有可能在函数体中传播它吗 定义my_func*参数,**kwargs:Python 体中的扩展函数args,python,Python,可能是个愚蠢的问题,但出于好奇 在python中,我可以在函数的签名中扩展*args和**kwargs def my_funcfoo,bar: printfoo={foo},bar={bar} 我的职责1,2 1 2 my_func1,bar=2 my_funcfoo=1,bar=2 有可能在函数体中传播它吗 定义my_func*参数,**kwargs: foo,bar=*args,**kwargs*args只是一个元组,**kwargs只是一个dict。你可以像其他任何东西一样使用它们 对于a
foo,bar=*args,**kwargs*args只是一个元组,**kwargs只是一个dict。你可以像其他任何东西一样使用它们 对于args中的arg: 对于名称,kwargs.items中的arg: 以下是关于这方面的指南: **kwargs,而不是%20被%20%20语言强制执行的%20。args是一个元组,而不是foo kwargs是一个dict,而不是bar的值 如果放弃使用签名,则必须明确位置参数到名称的映射。比如说,
def my_func(*args, **kwargs):
if len(args) == 0 and `foo` not in kwargs:
raise TypeError("Missing argument for 'foo'")
else:
try:
foo = args[0]
except IndexError:
foo = kwargs['foo']
if len(args) == 1 and `bar` not in kwargs:
raise TypeError("Missing argument for 'bar'")
else:
try:
bar = args[1]
except IndexError:
bar = kwargs['bar']
....
这里,我假设位置参数应该优先于关键字参数。您还可以使关键字参数优先
def my_func(*args, **kwargs):
if len(args) == 0 and `foo` not in kwargs:
raise TypeError("Missing argument for 'foo'")
else:
try:
foo = kwargs['foo'
except IndexError:
foo = args[0]
if len(args) == 1 and `bar` not in kwargs:
raise TypeError("Missing argument for 'bar'")
else:
try:
bar = kwargs['bar']
except IndexError:
bar = args[1]
....
或者继续将尝试同时使用两者视为错误:
def my_func(*args, **kwargs):
if len(args) == 0 and `foo` not in kwargs:
raise TypeError("Missing argument for 'foo'")
elif len(args) > 0 and `foo` in kwargs:
raise TypeError("Multiple attempts to assign foo")
else:
try:
foo = args[0]
except IndexError:
foo = kwargs['foo']
if len(args) == 1 and `bar` not in kwargs:
raise TypeError("Missing argument for 'bar'")
elif len(args) > 1 and `bar` in kwargs:
raise TypeError("Multiple attempts to assign bar")
else:
try:
bar = args[1]
except IndexError:
bar = kwargs['bar']
....
主要的问题是,通过使用*args、**kwargs声明函数,对foo和bar没有固有的顺序,除非我们稍后在函数体中强加一个顺序。但我们可以这样做:
def my_func(*args, **kwargs):
# we didn't say in the declaration what the arguments
# were meant to be, but now we want to impose an
# interpretation on the args,
params = ["foo", "bar"]
argsd = dict(zip(params, args))
# and fold in the kwargs
argsd.update(kwargs)
# unpack into variables, choosing names based on the
# params that we are using (this rather assumes that
# the params list has been hard-coded because we wouldn't
# want to try naming the local variables dynamically)
foo, bar = [argsd[k] for k in params]
print(f"foo={foo}, bar={bar}, args={args}, kwargs={kwargs}")
my_func(1, 2)
my_func(1, bar=2)
my_func(foo=1, bar=2)
my_func(bar=2, foo=1)
输出:
foo=1, bar=2, args=(1, 2), kwargs={}
foo=1, bar=2, args=(1,), kwargs={'bar': 2}
foo=1, bar=2, args=(), kwargs={'foo': 1, 'bar': 2}
foo=1, bar=2, args=(), kwargs={'bar': 2, 'foo': 1}
是的,我知道它们是什么。我想看看是否有可能把它们映射到行中的变量你是说像foo,bar=args,kwargs?我知道args和kwargs分别是元组和dict。在解决方案中,假设args[0]和kwargs['bar']已设置值。我想打破这个假设,能够做foo,bar=,{'foo':1,'bar':2}或foo,bar=1,2,{}或任何其他组合。用可能的函数调用更新了我的问题如果你只有位置参数,你可以在函数内随意调用任何一个。他们不是以任何特定的名字出现的,只是他们的职位。现在还不完全清楚你在问什么。def my_funcfoo,bar显式命名参数。使用*args则不起作用。kwargs也不命名任何参数,但至少每个关键字参数都有一个名称和一个值。在函数体中,我尝试在函数的符号中为您做些什么。i、 e将参数正确地分配给变量,不管它们是作为位置参数还是命名参数传入的,还是两者的混合传入的。如果没有我问题中的例子,我不知道如何更好地解释它
foo=1, bar=2, args=(1, 2), kwargs={}
foo=1, bar=2, args=(1,), kwargs={'bar': 2}
foo=1, bar=2, args=(), kwargs={'foo': 1, 'bar': 2}
foo=1, bar=2, args=(), kwargs={'bar': 2, 'foo': 1}