我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
给的想法.pack()
)-由于tk.Frame.__init__
(side
)和.pack()
(text
)的未知选项,程序将崩溃。
唯一的想法,我必须克服这是手动调度论据kwargs
来tk.Frame.__init__
,并.pack()
呼吁他们面前:
class Label(tk.Label):
def __init__(self, parent, *args, **kwargs):
# __init__ parameters
initparms = dict()
for p in ['text']:
if kwargs.get(p):
initparms[p] = kwargs.get(p)
# pack parameters
packparms = dict()
for p in ['side']:
if kwargs.get(p):
packparms[p] = kwargs.get(p)
tk.Label.__init__(self, parent, initparms)
self.pack(packparms)
它可以工作,但是有没有更好的方法(= pythonic)来实现呢?
如果您仅使用“文本”,则实际上并不需要每次都使用该列表。你可以做:
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)
这使逻辑的每个部分保持独立。
这有帮助吗?
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句