我将Label
子类化为自动.pack()
:
import Tkinter as tk
class Label(tk.Label):
def __init__(self, parent, *args, **kwargs):
tk.Label.__init__(self, parent, *args, **kwargs)
self.pack()
class App(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
l = Label(parent, text="word")
root = tk.Tk()
App(root).pack(side="top", fill="both", expand=True)
root.mainloop()
我希望能够在创建.pack()
的实例时将参数传递给Label
。
如上所述,所有kwargs
都会传递给父tk.Label
,因此我无法将我的调用更新为l = Label(parent, text="word", side=tk.LEFT)
(想法将**kwargs
传递给{{ 1}}) - 由于.pack()
(tk.Frame.__init__
)和side
(.pack()
)的未知选项,程序会崩溃。
我必须克服这一点的唯一想法是在调用它们之前手动将text
中的参数发送到kwargs
和tk.Frame.__init__
:
.pack()
它有效,但是有更好的(= pythonic)方法来实现这个目标吗?
答案 0 :(得分:0)
如果你只是使用'text',那么每次都不需要列表。你可以这样做:
if 'text' in kwargs:
initparms['text'] = kwargs['text']
使事情变得更好。
所以,如果你想一次做一大堆:
for param in ['text', 'another', 'option']:
if param in kwargs:
initparms[param] = kwargs[param]
此处不需要额外.get()
次来电。
从Python 2.7开始,您可以使用以下方法实际创建列表:
{key:value for key,value in ...}
语法。所以:
initparms = {k:v for k,v in kwargs.items()
if k in ['text','and','other','valid','params']}
然而,这有点难看,把这样的东西放在一个功能中间做其他事情有点不友好。
通常最好将事物分开以使功能变小。
VALID_LABEL_OPTIONS=['text', 'and', 'so', 'on']
VALID_PACK_OPTIONS = ['side', 'etc']
def extract_args(all_args, valid_keys):
return {k:v for k,v in all_args.items()
if k in valid_keys}
然后在__init__
函数中执行以下操作:
initparms = extract_args(kwargs, VALID_LABEL_OPTIONS)
packparms = extract_args(kwargs, VALID_PACK_OPTIONS)
将逻辑的每个部分分开。
这有帮助吗?