这是我从别人那里收到的一些代码,为什么需要 **kwargs?
This is some code I received from someone else, why is **kwargs needed?
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
try:
import tkinter as tk
except ImportError:
import Tkinter as tk
class CheckboxRow(tk.Frame):
def __init__(self, master, name, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
self.name = name
checkbox = tk.Checkbutton(self, text=name)
checkbox.pack(side=tk.LEFT)
deleteItem = tk.Button(self, text="x", bg="red", fg="white",
activebackground="white", activeforeground="red",
command=self.destroyCheckbox)
deleteItem.pack(side=tk.RIGHT)
def destroyCheckbox(self):
self.master.master.checkboxList.remove(self.name)
self.destroy()
class CheckboxArea(tk.Frame):
def add(self, name):
row = CheckboxRow(self, name)
row.pack(fill=tk.X)
class InputStuff(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
prompt = tk.Label(self, text="What do you want your checkbox to be for?")
prompt.pack()
bottomInput = tk.Frame(self)
self.entry = tk.Entry(bottomInput, bd=3)
self.entry.pack(side=tk.LEFT)
buttonConfirm = tk.Button(bottomInput, text="Confirm", command=self.drawCheckbox)
buttonConfirm.pack(side=tk.LEFT)
bottomInput.pack()
buttonDone = tk.Button(self, text = "Close Input", command=master.hide_input_stuff)
buttonDone.pack()
def drawCheckbox(self, event=None):
self.master.add(self.entry.get())
self.entry.delete(0, tk.END)
class MainWindow(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
master.protocol("WM_DELETE_WINDOW", self.on_closing)
self.checkboxList = []
self.checkbox_area = CheckboxArea(self)
self.checkbox_area.pack(fill=tk.X)
self.input_stuff = InputStuff(self)
self.add_button = tk.Button(self, text="Add Item", command=self.show_input_stuff)
self.hide_input_stuff() # start with "add" button active
self.load()
def add(self, name):
self.checkbox_area.add(name)
self.checkboxList.append(name)
def show_input_stuff(self):
self.add_button.pack_forget()
self.input_stuff.pack()
self.input_stuff.entry.focus()
self.master.bind('<Return>', self.input_stuff.drawCheckbox)
def hide_input_stuff(self):
self.input_stuff.pack_forget()
self.add_button.pack()
self.master.unbind('<Return>')
def load(self):
try:
with open('toDoListSaveFile.json') as infile:
checkboxList = json.load(infile)
for savedCheckbox in checkboxList:
self.add(savedCheckbox)
except (IOError, ValueError):
#an error occured while loading ... so no saved settings loaded
pass
def on_closing(self):
with open("toDoListSaveFile.json", 'w') as outfile:
json.dump(self.checkboxList, outfile)
self.quit()
def main():
master = tk.Tk()
master.title("To-Do List (with saving!)")
master.geometry("300x300")
win = MainWindow(master)
win.pack(fill=tk.X)
master.mainloop()
if __name__ == '__main__':
main()
**kwargs
在 class CheckboxRow 中。为什么需要它?据我所知,当你接受可变数量的参数时你只需要 **kwargs
,但是 __init__()
只会接受三个参数,self,
masterand
name`。
同tk.Frame.__init__
。为什么这里需要 kwargs?我很确定我应该如何使用 kwargs 是错误的,有人可以解释一下吗?
严格来说,不需要。但是,通过包含它,您可以将标准框架选项传递给 subclasses.
例如,使用 **kwargs
,您可以像这样设置框架的边框宽度:
x = CheckboxRow(root, "A row", borderwidth=1, relief="sunken")
原因是,borderwidth=1, relief="sunken"
包含在 kwargs
中,它被传递给继承的 Frame
class,它将接受这些参数。
如果您还从对 Frame.__init__
的调用中删除 **kwargs
,则可以从参数列表中省略它,缺点是您无法再传递有效的 Frame
选项:
class CheckboxRow(tk.Frame):
def __init__(self, master, name):
tk.Frame.__init__(self, master)
class CheckboxRow(tk.Frame):
def __init__(self, master, name, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
这样,任何用于初始化 CheckboxRow
实例的关键字都将:
- 被录取
- 被传给初始化一个
tk.Frame
查看您的代码,不查看 documentation.
就不可能知道 tk.Frame
将使用哪些关键字参数
这是一个没有 kwargs
的更简单的例子:
def f(x):
print x
f(2, width=800, height=600)
#=> TypeError: f() got an unexpected keyword argument 'width'
与kwargs
:
def f(x, **kwargs):
print x
g(**kwargs)
def g(**kwargs):
print kwargs
f(2, width=800, height=600)
# 2
# {'width': 800, 'height': 600}
kwargs 允许您传递可选的关键字参数。因此,如果您只想更改某些参数而不更改其他参数:
例如:
f = Frame(height=2, bd=1, relief=SUNKEN)
f = Frame(relief=SUNKEN) #This also works
f = Frame() # Also works
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
try:
import tkinter as tk
except ImportError:
import Tkinter as tk
class CheckboxRow(tk.Frame):
def __init__(self, master, name, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
self.name = name
checkbox = tk.Checkbutton(self, text=name)
checkbox.pack(side=tk.LEFT)
deleteItem = tk.Button(self, text="x", bg="red", fg="white",
activebackground="white", activeforeground="red",
command=self.destroyCheckbox)
deleteItem.pack(side=tk.RIGHT)
def destroyCheckbox(self):
self.master.master.checkboxList.remove(self.name)
self.destroy()
class CheckboxArea(tk.Frame):
def add(self, name):
row = CheckboxRow(self, name)
row.pack(fill=tk.X)
class InputStuff(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
prompt = tk.Label(self, text="What do you want your checkbox to be for?")
prompt.pack()
bottomInput = tk.Frame(self)
self.entry = tk.Entry(bottomInput, bd=3)
self.entry.pack(side=tk.LEFT)
buttonConfirm = tk.Button(bottomInput, text="Confirm", command=self.drawCheckbox)
buttonConfirm.pack(side=tk.LEFT)
bottomInput.pack()
buttonDone = tk.Button(self, text = "Close Input", command=master.hide_input_stuff)
buttonDone.pack()
def drawCheckbox(self, event=None):
self.master.add(self.entry.get())
self.entry.delete(0, tk.END)
class MainWindow(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
master.protocol("WM_DELETE_WINDOW", self.on_closing)
self.checkboxList = []
self.checkbox_area = CheckboxArea(self)
self.checkbox_area.pack(fill=tk.X)
self.input_stuff = InputStuff(self)
self.add_button = tk.Button(self, text="Add Item", command=self.show_input_stuff)
self.hide_input_stuff() # start with "add" button active
self.load()
def add(self, name):
self.checkbox_area.add(name)
self.checkboxList.append(name)
def show_input_stuff(self):
self.add_button.pack_forget()
self.input_stuff.pack()
self.input_stuff.entry.focus()
self.master.bind('<Return>', self.input_stuff.drawCheckbox)
def hide_input_stuff(self):
self.input_stuff.pack_forget()
self.add_button.pack()
self.master.unbind('<Return>')
def load(self):
try:
with open('toDoListSaveFile.json') as infile:
checkboxList = json.load(infile)
for savedCheckbox in checkboxList:
self.add(savedCheckbox)
except (IOError, ValueError):
#an error occured while loading ... so no saved settings loaded
pass
def on_closing(self):
with open("toDoListSaveFile.json", 'w') as outfile:
json.dump(self.checkboxList, outfile)
self.quit()
def main():
master = tk.Tk()
master.title("To-Do List (with saving!)")
master.geometry("300x300")
win = MainWindow(master)
win.pack(fill=tk.X)
master.mainloop()
if __name__ == '__main__':
main()
**kwargs
在 class CheckboxRow 中。为什么需要它?据我所知,当你接受可变数量的参数时你只需要 **kwargs
,但是 __init__()
只会接受三个参数,self,
masterand
name`。
同tk.Frame.__init__
。为什么这里需要 kwargs?我很确定我应该如何使用 kwargs 是错误的,有人可以解释一下吗?
严格来说,不需要。但是,通过包含它,您可以将标准框架选项传递给 subclasses.
例如,使用 **kwargs
,您可以像这样设置框架的边框宽度:
x = CheckboxRow(root, "A row", borderwidth=1, relief="sunken")
原因是,borderwidth=1, relief="sunken"
包含在 kwargs
中,它被传递给继承的 Frame
class,它将接受这些参数。
如果您还从对 Frame.__init__
的调用中删除 **kwargs
,则可以从参数列表中省略它,缺点是您无法再传递有效的 Frame
选项:
class CheckboxRow(tk.Frame):
def __init__(self, master, name):
tk.Frame.__init__(self, master)
class CheckboxRow(tk.Frame):
def __init__(self, master, name, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
这样,任何用于初始化 CheckboxRow
实例的关键字都将:
- 被录取
- 被传给初始化一个
tk.Frame
查看您的代码,不查看 documentation.
就不可能知道tk.Frame
将使用哪些关键字参数
这是一个没有 kwargs
的更简单的例子:
def f(x):
print x
f(2, width=800, height=600)
#=> TypeError: f() got an unexpected keyword argument 'width'
与kwargs
:
def f(x, **kwargs):
print x
g(**kwargs)
def g(**kwargs):
print kwargs
f(2, width=800, height=600)
# 2
# {'width': 800, 'height': 600}
kwargs 允许您传递可选的关键字参数。因此,如果您只想更改某些参数而不更改其他参数:
例如:
f = Frame(height=2, bd=1, relief=SUNKEN)
f = Frame(relief=SUNKEN) #This also works
f = Frame() # Also works