def foo(name, *args, **kwargs):
我需要删除*args
的前两个参数,以防它的长度(len(args)
)大于2。有可能吗?
这就是为什么我需要这样做: 我有以下功能:
def foo(name, xml='my.xml', xsd='my.xsd', *otherfiles):
print('name: ' + name)
print('xml: ' + xml)
print('xsd: ' + xsd)
print(otherfiles)
我需要在此函数的参数中添加一个可选的布尔参数,而不会破坏向后兼容性。所以我把功能更改为:
def foo2(name, *otherfiles, **kwargs):
kwargs.setdefault('relativePath', True)
if len(otherfiles)>0:
xml = otherfiles[0]
else:
kwargs.setdefault('xml', 'my.xml')
xml = kwargs['xml']
if len(otherfiles)>1:
xsd = otherfiles[1]
else:
kwargs.setdefault('xsd', 'my.xsd')
xsd = kwargs['xsd']
print('name: ' + name)
print('xml: ' + xml)
print('xsd: ' + xsd)
print(otherfiles)
现在我通过检查foo
和foo2
的输出是否相同来测试向后兼容性:
foo('my_name', '../my.xml', '../my.xsd', 'file1', 'file2')
print('===============================================================')
foo2('my_name', '../my.xml', '../my.xsd', 'file1', 'file2')
输出:
name: my_name
xml: ../my.xml
xsd: ../my.xsd
('file1', 'file2')
===============================================================
name: my_name
xml: ../my.xml
xsd: ../my.xsd
('../my.xml', '../my.xsd', 'file1', 'file2')
如您所见,应删除otherfiles
的前两项以维护旧功能。
答案 0 :(得分:1)
我们无法从args
中移除项目,因为它是tuple
。 由于tuple
是不可变的
但我们可以根据我们的逻辑创建包含args
项的新变量。我们可以使用新变量进行下一步处理。
<强> demo1的强>:
def foo(name, *args, **kwargs):
print "args: ", args
print "Type of args: ", type(args)
if len(args)>2:
tmp_args = args[0], args[1]
else:
tmp_args = args
print "Temp args:", tmp_args
print "Debug 1:"
foo("ww", 12,3,4,4,5,6,7,7)
print "\nDebug 2:"
foo("ss", 1)
Debug 1:
args: (12, 3, 4, 4, 5, 6, 7, 7)
Type of args: <type 'tuple'>
Temp args: (12, 3)
Debug 2:
args: (1,)
Type of args: <type 'tuple'>
Temp args: (1,)
如果我们在下一个过程中不需要来自变量的值,我们可以覆盖相同的变量名
演示2
def foo(name, *args, **kwargs):
print "args: ", args
print "Type of args: ", type(args)
if len(args)>2:
args = args[0], args[1] #- Created Same name variable.
print "Temp args:", args
答案 1 :(得分:0)
以下内容可能有助于在调用函数之前更改已命名参数列表。
添加参数:
# The wrapper adds a named argument 'age' to the function call
def decorator(func):
def wrapper(*args, **kwargs):
print("before")
# Add an argument to the existing list
kwargs.update(age=4)
func(*args, **kwargs)
print("after")
return wrapper
# Decorator replaces myFunc by a function which adds/changes the
# age argument before calling original myFunc
@decorator
def myFunc(name, age):
print(f"Hi {name} ! Are you {age} ?")
myFunc("Roger")
myFunc(name="Marc", age=33)
删除元素:
# The wrapper removes the inappropriate arguments from kwargs
def decorator(func):
def wrapper(*args, **kwargs):
print("before")
# Keep only expected names
# kwargs.pop("argname") works if we know the name to remove
new_kwargs = {k: v for k, v in kwargs.items() if k in ["name"]}
func(*args, **new_kwargs)
print("after")
return wrapper
# Decorator replaces myFunc by a function which filters
# argument(s) before calling original myFunc
@decorator def myFunc(name):
print(f"Hi {name} !")
myFunc(tutu=40, name="Roger", toto="eeee")
它不严格回答问题,但与标题相符,有人在接受的答案的评论中询问有关kwargs的问题。