【问题标题】:Python using super() for inheritancePython 使用 super() 进行继承
【发布时间】:2020-05-15 08:12:55
【问题描述】:

假设我有 2 个文件,用于显示 GUI 的 frontend.py 和用于数据库功能的 backend.py。我在使用 super() 继承数据库类时遇到问题。来自 #frontend.py 中 managerPage 类中的 #backend2.py

我有错误:

frame = F(container, self) TypeError: init() 缺少 2 个必需的位置参数:'cn' 和 'cur'

我相信这与我在 managerPage 类中继承的 tk.Frame 类中的 init 有关。我相信 selfService 类(我为自己重命名)归功于用户@BryanOakley。有人可以帮我成功利用 super()。

前端.py。

import backend2

class selfService(tk.Tk, Toplevel):

    def __init__(self, *args, **kwargs):
        #Toplevel.__init__(self)
        self.employeeWindow = None


        tk.Tk.__init__(self, *args, **kwargs)
        self.container = tk.Frame(self)

        self.container.pack(side="top", fill="both", 
        expand = True)

        self.container.grid_rowconfigure(0, 
        weight=1)
        self.container.grid_columnconfigure(0, 
        weight=1)

        self.frames = {}


        selfService.restart = False

        for F in (StartPage, PageOne, PageTwo):

        self.frame = F(self.container, self)

        self.frames[F] = self.frame

        self.frame.grid(row=0, column=0, 
        sticky="nsew")

        self.show_frame(StartPage)


    def show_frame(self, cont):
        self.frame = self.frames[cont]
        self.frame.tkraise()

class managerPage(tk.Frame, 
    validation.account_validation,backend2.Database):
    def __init__(self, parent, controller, cn, cur):
        tk.Frame.__init__(self,parent)
        super().__init__(cn, cur)

        print(self.cn)

backend2.py

class Database():
    def __init__(self):
        self.config = {
        'user': 'root',
        'password': 'root',
        'host': 'localhost',
        'database': 'myDatabase'}

        self.cn = 
        mysql.connector.connect(**self.config)
        self.cur = self.cn.cursor()

【问题讨论】:

  • 您使用继承的方式暗示您不应该使用继承。您确定希望每个页面都有自己的独立数据库连接吗?即:如果您有 3 个页面,您将有 3 个不同的数据库连接。这是一个不寻常的设计。

标签: python-3.x oop inheritance tkinter super


【解决方案1】:

继承不适用于在两个不同对象之间共享数据。您的 managerPage 不应继承您的 Database 类。页面不能同时是页面和数据库。如果您使用继承,每个实例都将是数据库的一个单独实例。

相反,您应该创建Database 类的单个实例,并将该实例传递给需要它的页面。或者在控制器上添加一个可以返回实例的方法。

例如,您可以在控制器的__init__ 中创建数据库实例:

class selfService(tk.Tk):

    def __init__(self, *args, **kwargs):
        ...
        self.db = Database()
        ...

然后,在任何引用控制器的代码中,您都可以使用self.controller.db 访问数据库,如下例所示:

class managerPage(tk.Frame):
    def __init__(self, parent, controller):
        self.controller = controller
        ...
        print(self.controller.db)

(作为旁注,您不应该继承 Tk Toplevel。其中之一,但不能同时继承)。

【讨论】:

  • 好的。谢谢。但是在 selfService 中实例化 db 类时,我会遇到错误:return getattr(self.tk, attr) AttributeError: '_tkinter.tkapp' object has no attribute 'db'
  • @grimReaperZ:就像我的第一个示例所示,您必须定义 self.db
猜你喜欢
  • 2020-11-27
  • 2016-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多