Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在提供关键字参数后是否可以提供*args?_Python_Python 3.x_Tkinter - Fatal编程技术网

Python 在提供关键字参数后是否可以提供*args?

Python 在提供关键字参数后是否可以提供*args?,python,python-3.x,tkinter,Python,Python 3.x,Tkinter,我试图通过先提供所有位置参数和非位置参数,然后再提供其余非关键字参数来重写函数。 以下是所采取步骤的函数: def foo(a,b,c=3,*args,**kwargs): 打印(f“位置:a={a}| b={b}| c={c}”) 打印(“*args”,args) 打印(“**kwargs”,kwargs) 从functools导入部分 #稍后可调用以提供*args的部分 部分=部分(foo,a=2,b=4,c=3,额外=3) #在这里,我希望调用额外的参数 #但却引发了类型错误 第(a)、(

我试图通过先提供所有位置参数和非位置参数,然后再提供其余非关键字参数来重写函数。

以下是所采取步骤的函数:

def foo(a,b,c=3,*args,**kwargs):
打印(f“位置:a={a}| b={b}| c={c}”)
打印(“*args”,args)
打印(“**kwargs”,kwargs)
从functools导入部分
#稍后可调用以提供*args的部分
部分=部分(foo,a=2,b=4,c=3,额外=3)
#在这里,我希望调用额外的参数
#但却引发了类型错误
第(a)、(b)、(c)部分
但出现了一个错误

---------------------------------------------------------------------------
TypeError回溯(最近一次调用上次)
在()
11#在这里,我希望会调用额外的参数
12#但instread会引发类型错误
--->第13部分(“a”、“b”、“c”)
TypeError:foo()为参数“a”获取了多个值
这个问题有没有解决办法,不用深入阅读它的 可调用的签名(例如使用
inspect.signature
等)

编辑:

以下是回溯的真正问题代码:

将tkinter作为tk导入
从tkinter导入ttk
定义生成器(父级、标签、wtype、*args、**kwargs):
"""
函数为configbox构建小部件。
"""
#creae与父容器框架
容器=ttk.Frame(父级)
容器包装(fill='x')
#在容器中添加元素
# =================================
#包装标签
label=ttk.label(容器,文本=label)
标签.包装(侧面='left',padx=4,pady=4,填充='x')
#按名称获取小部件并实例化
#(此处失败)
widget=getattr(ttk,wtype)(容器,*args,**kwargs)
#打包并返回
pack(side='right',padx=4,pady=4,fill='x')
返回小部件
类配置框(tk.Toplevel):
定义初始化(自、父、*args、**kwargs):
super()
lframe=ttk.Labelframe(self,text=“配置”)
lframe.pack()
#这不会失败-(无*args或**kwargs)
#放置分机输入框
ext\u entry=\u builder(lframe,“扩展”,“条目”)
#这部分失败了!
#使用选项菜单绑定后端变量
bkndvar=tk.StringVar(lframe,value=“#XXX测试”)
bknd\u选项=\u生成器(
L框架,
“后端”,
“选项菜单”,
#给*args。。。
*(“测试1”、“测试2”),
#…和**kwargs(此处失败)
**dict(variable=bkndvar,default=bkndvar.get()),
)
回溯:

>x=\u配置框(tk.tk())
>>>x.mainloop()
---------------------------------------------------------------------------
TypeError回溯(最近一次调用上次)
在()
---->1 x=\u配置框(tk.tk())
2 x.mainloop()
在uuu init_uuuu中(self、parent、*args、**kwargs)
45
46#…和**kwargs(此处失败)
--->47**dict(变量=bkndvar,默认值=bkndvar.get()),
48         )
在构建器中(父级、标签、wtype、*args、**kwargs)
15#按名称获取小部件并实例化
16#(此处失败)
--->17 widget=getattr(ttk,wtype)(容器,*args,**kwargs)
18
19#打包并返回
TypeError:\uuuu init\uuuuu()为参数“variable”获取了多个值

partial
的关键字参数与其包装的函数的命名参数不匹配;它只是保存它们以添加到
partial
对象稍后接收的参数中。也就是说,
part(foo,a=2,b=4,c=3,extra=3)('a','b','c')
完全等同于
foo('a','b','c',a=2,b=4,c=3,extra=3)

您需要将位置参数传递给对
partial
的调用

part = partial(foo, 2, 4, 3, extra=3)
然后您将得到您想要的结果:

>>> part('a', 'b', 'c')
Positional: a=2 | b=4 | c=3
*args ('a', 'b', 'c')
**kwargs {'extra': 3}

请注意,调用
foo('a','b','c',a=2,b=4,c=3,extra=3)时遇到的错误与调用
时相同。您想按关键字提供
a
b
c
有什么原因吗?这与
tkinter
有关。为了不那么冗长,我提出了一个更简单的情况。在tkinter中,我想创建一个构建器函数,在这个函数中,我可以简单地提供对象的名称,并将其余的参数作为关键字传递,但不是每个tkinter对象都有相同的调用签名,还有一些采用*参数(例如,
OptionMenu
。在我的工作环境中,我不知道传入可调用对象的调用签名,因此我希望尽可能灵活。这是一个问题:如何调用签名未知的函数?它与
tkinter
相关。tkinter对象具有不同的签名,但我希望通过创建一个函数来简化tk小部件的创建,该函数将采用tkinter对象的名称和它的其余参数。我是否必须通过创建一个装饰器或使用
inspect.signature
?您的问题应该从一开始就包括您的实际用例。这将非常详细,并且就像我在这里展示的一样。