tkinter, передавая * args * kwargs в super () .__ init__ - PullRequest
0 голосов
/ 16 марта 2019

Я бы спросил, почему этот код работает

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'

есть предложения?

пожелания

обновление

после @Bryan Oakley note я хотел бы добавить некоторые соображения.

0) Я понял, что kwargs принимает только ключевые значения по умолчанию:

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)

, которые возвращают

my init args ('x', 'y ',' z ')

my init kwargs {' baseName ':' foo ',' className ':' bar '}

my super args ()

мои суперкварги {{baseName ':' foo ',' className ':' bar '}

1) но аргументы?

на работе, где яУ меня Windows, я могу передать аргументы, в Linux, Debian 9, он возвращает

ошибка, для этого я поставил исключение, например:

_tkinter.TclError: не удалось подключиться к дисплею "x"

Извините, что я так деликатен в этом вопросе, но я просто пока не понимаю.

Ответы [ 4 ]

1 голос
/ 16 марта 2019

Версия вашего кода с super().__init__(*args, **kwargs) не работает, потому что ваш родительский класс (tkinter.Tk) не поддерживает передаваемые аргументы.

Мне не ясно, что именно вы ожидаете от этих аргументов. Это не вещи, о которых tkinter обычно заботятся, поэтому нет необходимости передавать их. Если они заботятся о вашем классе, вы, вероятно, захотите явно назвать их в качестве аргументов, а не использовать *args и **kwargs.

0 голосов
/ 24 апреля 2019

Я возобновляю это обсуждение, потому что я нашел бы способ сделать то, что я хотел, а именно, передать несколько произвольных аргументов или kwargs классу, когда мы запускаем скрипт tkinter.

Посмотрите на этот скрипт, класс класса App наследуется от 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(App, self).__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()
0 голосов
/ 19 марта 2019

Рассмотрим этот код:

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__ передавались только допустимые опции суперклассу. Ваш класс вполне может принять эти параметры и делать с ними все, что захочет, но вы не должны передавать эти аргументы суперклассу.

0 голосов
/ 16 марта 2019

super().__init__() инициализирует суперкласс App,, который равен tk.Tk.Когда вы вызываете App(*args,**kwargs), вы передаете именованные параметры kwargs в tk.Tk() через super().__init__(*args, **kwargs).По крайней мере один из параметров ('passw') не распознается tk.Tk().На самом деле, ни один из них не распознается, но первый нераспознанный вызывает сбой программы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...