tkinter, passing *args *kwargs on super().__init__



我会问为什么此代码工作

import tkinter as tk
class App(tk.Tk):
    def __init__(self, *args, **kwargs):            
        super().__init__()    
        print(args,kwargs)            
        self.title("Hello World")
        self.geometry("400x300")
if __name__ == '__main__':
    args = ('Y','Y','Z')
    kwargs = {'server':"127.0.0.1",'user':"guest",'passw':"12345",'database':"genbank"}    
    app = App(*args,**kwargs)

,但是如果我替换

super().__init__()

super().__init__(*args, **kwargs)

应该是正确的方法,它不起作用。

它返回

super().__init__(*args, **kwargs)
TypeError: __init__() got an unexpected keyword argument 'passw'

有什么建议?

问候

update

@Bryan Oakley注意,我想添加一些注意事项。

0)我知道夸尔格斯仅接受:

的密钥默认值

class tkinter.tk(screenname = none,basename = none,className ='tk',usetk = 1)

import tkinter as tk
class App(tk.Tk):
    def __init__(self, *args, **kwargs):
        print("my __init__  args {}".format(args))
        print("my __init__  kwargs {}".format(kwargs))
        try:
            super().__init__(*args, **kwargs)
        except:
            args = ()
            super().__init__(*args, **kwargs)
        print("my super args {}".format(args))
        print("my super kwargs {}".format(kwargs))
        self.title("Hello World")
        self.geometry("400x300")
if __name__ == '__main__':
    args = ('x','y','z')
    kwargs = {'baseName':'foo','className':'bar'}
    app = App(*args,**kwargs)

返回

我的 init args('x','y','z')

我的 init kwargs {'basename':'foo','className':'bar'}

我的超级args()

我的Super Kwargs {'Basename':'foo','className':'bar'}

1)但是args?

在工作中,我可以通过我可以通过args的Windows OS,在Linux,Debian 9上,它返回

一个错误,为此,我已经例外,例如:

_tkinter.tclerror:无法连接到显示" x"

我很抱歉对此如此密集,但我只是还不知道。

从https://docs.python.org/3/library/tkinter.html#tkinter.tk上的函数定义中可以看到 class tkinter.Tk(screenName=None, baseName=None, className='Tk', useTk=1),它不支持您传递给它的任何夸尔格。

我建议


import tkinter as tk
class App(tk.Tk):
    def __init__(self, *args, **kwargs):
        
        # Pop and store your kwargs into variables of the class
        # Make sure to pop out all your defined keys in kwargs as below
        self._server = kwargs.pop('server')
        self._user = kwargs.pop('user')  
        self._password = kwargs.pop('passw')  
        self._database = kwargs.pop('genbank')    
        
        # And pass the args and kwargs
        super().__init__(*args, **kwargs)  
            
        self.title("Hello World")
        self.geometry("400x300")
if __name__ == '__main__':
    args = ('Y','Y','Z')
    kwargs = {'server':"127.0.0.1",'user':"guest",'passw':"12345",'database':"genbank"}    
    app = App(*args,**kwargs)

使用super().__init__(*args, **kwargs)的代码版本不起作用,因为您的父级(tkinter.Tk)不支持您要通过的参数。

对我来说,确切期望这些论点会做什么。它们不是tkinter通常关心的东西,因此无需将它们传递。如果它们是您的班级确实在乎的事情,您可能想明确地将其命名为参数,而不是使用*args**kwargs

考虑此代码:

kwargs = {'server':"127.0.0.1",'user':"guest",'passw':"12345",'database':"genbank"}    
app = App(*args,**kwargs)

它在功能上与此相同:

app = App(server="127.0.0.1", user="guest", passw="12345", database="genbank")

现在考虑以下代码:

super().__init__(*args, **kwargs)

super()返回基类,在这种情况下为Tk。因此,您的代码在功能上等同于此:

Tk(server="127.0.0.1", user="guest", passw="12345", database="genbank")

由于serveruserpasswdatabase不受Tk类的支持,因此会引发错误。

解决方案是要确保在调用super().__init__时仅将选项传递给超类。您的类都可以接受这些选项并对其做任何事情,但是您不应该将这些论点传递给超级类。

super().__init__()初始化App,的超类,即tk.Tk。调用App(*args,**kwargs)时,您将命名参数kwargs通过super().__init__(*args, **kwargs)传递给tk.Tk()tk.Tk()识别至少一个参数('passw')。实际上,它们都没有得到认可,但是第一个未被认可会导致程序崩溃。

我恢复了讨论,因为当我们启动tkinter脚本时,我会找到一种做我想做的事情,即将许多任意的args或kwargs转到一类。

查看此脚本,类别类应用程序从TK继承,但在启动

时接收列表,args和dict,kwargs

args =('y','y','z')

kwargs = {'passw':'12345','user':'guest','server':'127.0.0.1','database':'genbank'}

app = app(*args,** kwargs)

app.mainloop()

import tkinter as tk
class App(tk.Tk):
    def __init__(self, *args, **kwargs):
        super().__init__()
        print("args type: {}".format(type(args)))
        for i in args:
            print(i)
             
        print("kwargs type: {}".format(type(kwargs)))
        for k, v in kwargs.items():
            print(k,v)
        self.title("Hello World")
        self.geometry("400x300")
if __name__ == '__main__':
    args = ('Y','Y','Z')
    kwargs={'passw': '12345', 'user': 'guest', 'server': '127.0.0.1','database': 'genbank'}
    app = App(*args, **kwargs)
    app.mainloop()

最新更新