kesalahan tkinter dua pemain game pong

saya mencoba mengeksekusi kode ini:

import Tkinter as tk
import tkFont
import functools
import math
import random
import time

class Pong(tk.Canvas):

    DEFAULTS = dict(width=640, height=480,background='black',highlightthickness=0)

    def main(cls):
        root = tk.Tk()
        root.title('Pong')
        root.resizable(False, False)
        root.bind_all('<Escape>', lambda event: root.destroy())
        game = cls(tkFont.Font(family='Book Antiqua', size=15, weight='bold'), 5, 100,background='black', width=640, height=480)
        game.grid()
        root.mainloop()

tapi saya punya kesalahan itu:

Traceback (most recent call last):
   line 413, in <module>
    pong.main()
  , line 17, in main
    game = cls(tkFont.Font(family='Book Antiqua', size=15, weight='bold'), 5, 100,background='black', width=640, height=480)
AttributeError: Pong instance has no __call__ method

person user3200290    schedule 15.01.2014    source sumber
comment
Apa cls yang Anda lewati?   -  person aIKid    schedule 16.01.2014
comment
Bisakah Anda menunjukkan kepada kami saluran 413 tempat Anda menelepon pong.main() dan sedikit sebelum tempat Anda menugaskan pong?   -  person poke    schedule 16.01.2014
comment
jika nama == 'utama': pong = Pong() Pong.main()   -  person user3200290    schedule 16.01.2014
comment
baris 413, di ‹module› Pong.main() TypeError: metode tidak terikat main() harus dipanggil dengan instance Pong sebagai argumen pertama (bukannya tidak mendapat apa-apa)   -  person user3200290    schedule 16.01.2014


Jawaban (3)


Saya dapat melihat satu masalah utama sejauh ini

cls masuk sebagai variabel

def main(cls):  

Kemudian Anda menggunakannya seperti sebuah fungsi

game = cls(tkFont.Font(family='Book Antiqua', size=15, weight='bold'), 5, 100,background='black', width=640, height=480)
person Aidan    schedule 15.01.2014

Seperti yang Anda sebutkan di komentar, inilah cara Anda membuat pong dan memanggil main:

if __name__ == '__main__':
    pong = Pong()
    pong.main()

Pada saat Anda memanggil Pong(), Anda sedang membuat instance. Oleh karena itu, metode main yang Anda panggil adalah metode instance dengan parameter implisit pertama adalah instance itu sendiri. Biasanya parameter ini diberi nama self misalnya metode—bukan cls seperti yang Anda lakukan.

Jadi kalau kita ganti namanya, jelas apa yang gagal setelahnya:

game = self(tkFont.Font(…), 5, 100, background='black', width=640, height=480)

Ingatlah bahwa self adalah objek, dan turunan dari Pong. Jadi ini bukan fungsi dan bukan konstruktor yang bisa Anda panggil; Anda sebenarnya mencoba memanggil instance yang tidak berfungsi di sini.

Saya pikir apa yang sebenarnya ingin Anda lakukan adalah menjadikan main sebagai metode "statis", menjadi titik masuk ke aplikasi Anda. Dalam hal ini, Anda harus menambahkan dekorator @classmethod di depan deklarasi metode:

@classmethod
def main(cls):
    root = tk.Tk()
    # …

Dalam hal ini, cls memang akan menjadi tipe Pong, yang nantinya dapat Anda panggil untuk membuat objek Pong.

Anda harus mengubah bagian __name__ == '__main__ menjadi Pong.main() saja, karena Anda tidak lagi memanggil main untuk instance tetapi tipe keseluruhan.

if __name__ == '__main__':
    Pong.main()
person poke    schedule 15.01.2014
comment
Saya telah melakukan apa yang Anda maksud dan saya mengalami kesalahan: Pong.main() TypeError: metode tidak terikat main() harus dipanggil dengan instance Pong sebagai argumen pertama (bukannya tidak mendapat apa-apa) - person user3200290; 16.01.2014
comment
@ user3200290 Sepertinya Anda lupa menambahkan baris @classmethod di depan def main. - person poke; 16.01.2014
comment
maaf, itu karena saya lupa memasang dekorator tetapi sekarang saya mengalami kesalahan ini: Pong.main() AttributeError: class Pong tidak memiliki atribut 'main' - person user3200290; 16.01.2014
comment
Uhm, pastikan lekukanmu masih benar, agar fungsinya masih menjadi bagian dari kelas Pong. - person poke; 16.01.2014

Anda melakukan hal yang sangat aneh -- Anda membuat subkelas tk.Canvas, namun Anda tidak menginisialisasi tk sampai Anda membuat objek ini. Itu bukan cara yang tepat untuk menggunakan tkinter. Anda harus menginisialisasi Tk di luar cakupan kelas ini, atau jangan mewarisi dari tk.Canvas.

Saya sarankan Anda merestrukturisasi kode Anda sehingga Anda menginisialisasi tkinter terlebih dahulu, dan kemudian membuat instance game Anda.

Misalnya:

import Tkinter as tk

class Pong(tk.Canvas):
    def __init__(self, root):
        tk.Canvas.__init__(self, root)
        <put other "main" code here if you want>

if __name__ == "__main__":
    root = tk.Tk()
    pong = Pong(root)
    pong.pack(fill="both", expand=True)
    root.mainloop()
person Bryan Oakley    schedule 16.01.2014