1

我是 Python 的初学者,目前正在阅读我的书“绝对初学者的 Python 编程”的第 10/12 章。我了解 Python 中的 OOP,但由于一章(讨论了一些有关 OOP 的相关信息)是基于一个用于玩“纸牌”的程序,我不得不跳过该章的一部分(因为我不知道如何玩纸牌)和所以我错过了本书此时应该知道的重要信息。我这么说的原因是因为我需要一个简单的答案来回答我的问题,因为复杂的答案可能对我来说太难解释了。

但无论如何这是我的问题,我的书中有一段代码创建了一个简单的 GUI 程序(我完全理解),然后有一个我不理解的程序的面向对象版本(主要部分在 ' ## 的)。它包含一个叫做“超类构造函数”的东西,这完全让我感到困惑(我尝试对它进行一些研究,但它对我来说没有意义)。如果有人可以帮助向我解释第二版代码的工作原理(或提供有用的资源),那么我将不胜感激:

第一版代码:

from tkinter import *

# create a root window
root = Tk()
root.title("Lazy Buttons")
root.geometry("200x85")

app = Frame(root)
app.grid()

bttn1 = Button(app, text = "This is a button")
bttn1.grid()

root.mainloop()

第二个版本:

from tkinter import *

class Application(Frame):

    def __init__(self, master): # Why is 'master' called?
        super(Application, self).__init__(master)    # ?
        self.grid()
        self.create_widgets()

    def create_widgets(self):
        self.bttn1 = Button(self, text = "This is a button")
        self.bttn1.grid()

root = Tk()
root.title("Lazy Buttons 2")
root.geometry("200x85")
app = Application(root)
root.mainloop()
4

2 回答 2

1

不要因为您不了解问题领域而跳过教程的某些部分——您不需要知道如何玩纸牌就可以了解纸牌游戏代码与程序所做的事情之间的关系。对于您的实际问题:

class Application(**Frame**):

这将创建一个从类Application继承的类Frame。如果您不知道继承,您正在遵循的教程应该解释它,或者您可以尝试我刚刚搜索的类和继承的介绍。

**def __init__(self, master):

这将创建一个名为 的方法__init__。这是 Python 中的一种特殊方法,其行为类似于其他语言中的构造函数——本质上,每当Application创建 an 时,Python 将立即调用其__init__方法,然后将新对象返回给创建它的人。master只是一个参数,与任何其他函数的任何其他参数相同。

super(Application, self).__init__(master)

这会调用超类的构造函数,让它初始化新对象。super(Application, self)弄清楚超类什么(在这种情况下是Frame;在您最终会遇到的更复杂的情况下,这更难解决,并且super' 的魔法变得很重要)。

self.create_widgets()**

这将调用create_widgets您在此下方定义的方法。之前的对象.作为第一个参数传递到方法中,self- 因此,这在调用您所在的方法的同一对象上调用不同的方法。

app = Application(root)

这会创建一个Application- 通过调用类来创建对象,就像list()创建列表一样。您传入的参数__init__作为第二个参数传递(ApplicationPython 在幕后创建的新参数作为第一个参数传递,self,如上)。Python 创建一个 new Application,为您调用它__init__,然后将新对象分配给名称“app”。

于 2012-08-17T11:13:03.647 回答
0

这里的“超级”部分只是为了正确调用基类(您继承的类)的构造函数。让我们考虑以下示例:

class Device():  # class representing some drawing device
    ...
    def fill(self, color)
        ...  # actual code for draw on this device

screen = Device()
WHITE_COLOR = (255, 255, 255)

class Window(object):
    def __init__(self, width, height):
        self.width  = width
        self.height = height

    def area(self):
        return self.width * self.height

class ColoredWindow(Window):
    def __init__(width, height, color):
        super(ColoredWindow, self).__init__(width, height)
        self.color = color

    def fill(self):
        screen.fill(self.width, self.height, self.color)

my_window = ColoredWindow(640, 480, WHITE_COLOR)
my_window.fill()

这里的第一个类Window是一个通用窗口,它具有在构造函数中传递widthheight属性。 ColoredWindow是 的子类Window,它具有附加属性color。当ColoredWindow被构造时,它需要以某种方式将参数传递给它的基width类。heightWindow

这正是建筑super(ColoredWindow, self).__init__(width, height)的目的。第一部分,super(ColoredWindow, self)返回对基类的引用(Window在我们的例子中),第二部分,__init__(width, height)只是用正确的参数调用它的构造函数。

在你的例子master中没有被调用,它只是类__init__方法的参数Application

于 2012-08-17T11:54:56.357 回答