这是我从别人那里收到的一些代码,为什么需要** kwargs?

时间:2017-02-11 23:33:31

标签: python python-3.x class kwargs

#!/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在CheckboxRow类中。为什么需要它?据我所知,当您接受可变数量的参数时,您只需要**kwargs,但__init__()只会采用三个参数self, master and name`。

tk.Frame.__init__相同。为什么需要kwargs?我很确定我应该如何使用 kwargs ,有人可以解释一下吗?

3 个答案:

答案 0 :(得分:3)

严格来说,不需要它。但是,通过包含它,您可以将标准框架选项传递给子类。

例如,使用**kwargs,您可以设置框架的边框宽度,如下所示:

x = CheckboxRow(root, "A row", borderwidth=1, relief="sunken")

原因是borderwidth=1, relief="sunken"kwargs中包含的内容,并且它被传递给将继承这些参数的继承的Frame类。

如果您还要从**kwargs调用中删除Frame.__init__,则可以从参数列表中省略Frame,但缺点是您无法再传递有效的class CheckboxRow(tk.Frame): def __init__(self, master, name): tk.Frame.__init__(self, master) 选项:< / p>

class CheckboxRow(tk.Frame):
    def __init__(self, master, name, **kwargs):
        tk.Frame.__init__(self, master, **kwargs)

答案 1 :(得分:0)

CheckboxRow

这样,用于初始化tk.Frame实例的任何关键字都将:

  • 被接受
  • 传递给tk.Frame
  • 的初始化

查看您的代码,如果不查看documentation,就无法知道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}

{{1}}

答案 2 :(得分:0)

kwargs允许您传递可选的关键字参数。所以如果你只想改变一些论点而不是其他论点:

例如:

f = Frame(height=2, bd=1, relief=SUNKEN)
f = Frame(relief=SUNKEN) #This also works
f = Frame() # Also works