我会问为什么此代码工作
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")
由于server
,user
,passw
和database
不受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,kwargsargs =('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()