python - 接收 TypeError : object. __new__() 在 __new__ 未更改时不带任何参数

标签 python python-3.x tkinter

以下是使用 PyCharm Community Edition 中的 Tkinter 在 Python 3.0 中对 Conway 的生命游戏的不完整实现。

程序由四个文件组成:

  • Cell.py:包含一个 Cell 的类
  • Grid.py:包含生命游戏网格类
  • Windows.py:包含一个用于 tkinter 布局的类
  • main.py : 执行脚本

单元格.py:

from random import randint
from tkinter import *

class Cell:
    def __init__(self, master, state=None):
        if state is None:
            state = randint(0,2)
        self.state = state
        self.next_state = state
        self.button = Button(master, width=2, height=1, bg = 'black' if self.state == 1 else 'white').pack(side=LEFT)

    def __del__(self):
        self.button.destroy()

    def set_next_state(self, neighbours):
        if self.state == 1:
            self.next_state = 0 if neighbours < 2 or neighbours > 3 else 1
        else:
            self.next_state = 1 if neighbours == 3 else 0

    def update(self):
        self.state = self.next_state
        self.button.config( bg = 'black' if self.state == 1 else 'white')

网格.py:

from tkinter import *
from Cell import Cell

class Grid:
    def __init__(self, master, rows=15, cols=15, wraparound=True, pattern=None):
        self.master = master
        self.rows = rows
        self.cols = cols
        self.wraparound = wraparound

        if len(self.pattern) == rows*cols:  self.pattern = pattern
        else:  self.pattern = None

        self.create_frames()
        self.create_cells()

    def create_frames(self):
        self.frames = [Frame(self.master).pack(side=TOP) for r in range(self.rows)]

    def destroy_frames(self):
        for r in range(self.rows):
            self.frames[r].destroy()

    def create_cells(self):
        self.cells = {}
        for r in range(self.rows):
            for c in range(self.cols):
                if self.pattern is None:  self.cells[(r,c)] = Cell(self.frames[r])
                else:  self.cells[(r,c)] = Cell(self.frames[r], state=self.pattern[r*self.cols+c])

    def destroy_cells(self):
        for r in range(self.rows):
            for c in range(self.cols):
                del self.cells[(r,c)]

    def count_neighbours(self, r, c):
        offsets = [(i,j) for j in range(-1,2) for i in range(-1,2)]
        offsets.remove((0,0))
        neighbours = 0
        for offset in offsets:
            if self.wraparound:
                neighbours += self.cells[((r+offset[0])%self.rows, (c+offset[1])%self.cols)].state
            else:
                if r+offset[0] >= self.rows or r+offset[0] < 0 or c+offset[1] >= self.cols or c+offset[1] < 0:
                    neighbours += 0
                else:
                    neighbours += self.cells[(r+offset[0], c+offset[1])].state
        return neighbours

    def calculate_next_state(self):
        for r in range(self.rows):
            for c in range(self.cols):
                neighbours = self.count_neighbours(r,c)
                self.cells[(r,c)].set_next_state(neighbours)

    def update_cells(self):
        for r in range(self.rows):
            for c in range(self.cols):
                self.cells[(r,c)].update()

    def step(self):
        self.calculate_next_state()
        self.update_cells()

     def load_pattern(self, rows=10, cols=10, wraparound=True, pattern=None):
        self.destroy_cells()
        self.destroy_frames()

        self.rows = rows
        self.cols = cols
        self.wraparound = wraparound
        self.pattern = pattern

        self.create_frames()
        self.create_cells()

window .py:

from Grid import Grid
from tkinter import *

class MainWindow:
    def __init__(self, rows=10, cols=10, wraparound=True, pattern=None):
        self.root = Tk()

        grid_frame = Frame(self.root).pack(side=TOP)
        self.grid = Grid(grid_frame, rows=rows, cols=cols, wraparound=wraparound, pattern=pattern)

        button_frame = Frame(self.root).pack(side=BOTTOM)
        self.time_interval = 1000
        self.start_stop_button = Button(button_frame, text='START', command=self.start_stepper).pack(side=LEFT)
        self.step_button = Button(button_frame, text='STEP', command=self.grid.step)

        self.menubar = Menu(self.root)
        self.menubar.add_command(label='Change Time Interval', command=self.change_time_interval)
        self.root.config(menu=self.menubar)

        self.root.mainloop()

    def change_time_interval(self):
        # Incomplete
        pass

    def start_stepper(self):
        # Incomplete
        pass

    def stop_stepper(self):
        # Incomplete
        pass

主.py:

from Windows import MainWindow
game = MainWindow()

当我运行 main.py 时,我得到以下输出:

输出:

Traceback (most recent call last):
  File "C:/Users/Tyler/PycharmProjects/GameOfLife/main.py", line 3, in <module>
    game = MainWindow()
  File "C:\Users\Tyler\PycharmProjects\GameOfLife\Windows.py", line 9, in __init__
    self.grid = Grid(grid_frame, rows=rows, cols=cols, wraparound=wraparound, pattern=pattern)
TypeError: object.__new__() takes no parameters

我对此束手无策,因为我从未覆盖默认的 __new__ 方法。在检查了所有其他此类堆栈溢出问题后,大多数解决方案都将某种形式的拼写 __init__ 更正为 __init__。我对 python 脚本编写相对较新,因此非常感谢任何帮助调试它并解释为什么会产生错误。

最佳答案

Tkinter 有一个名为 Grid 的类,它隐藏了您自己的同名类,因为您在导入自己的类后使用了 from tkinter import *

有几种可能的解决方案:

  1. 将您的导入更改为 from Grid import Grid as MyGrid,然后在您想使用自己的 Grid 类时调用 MyGrid
  2. 将您的 from Grid import Grid 导入移动到 tkinter 之后(只要您不需要使用 tkinter Grid 类)。
  3. 将您的 tkinter 导入更改为 import tkinter 并使用 tkinter.Frame 等访问 tkinter 类(如 Frame)。
  4. 将类(class)名称更改为其他名称。

关于python - 接收 TypeError : object. __new__() 在 __new__ 未更改时不带任何参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38044773/

相关文章:

android - 如何使用 PGS4A 从 Pygame 创建 APK?

python - 如何将非对称成对距离矩阵转换为字典?

python - scipy curve_fit多系列数据

python - 将最后一行添加 n 次到时间索引数据框,同时每次将日期增加 1 天

python - 如何在 Python3 中找到给定排行榜的排名?

python - tkinter (python) 中的 IPAD-X/Y 和 PAD-X/Y 是否不同?

Python 填充字符串以对齐 Tkinter ListBox 小部件中的列

python - 如何允许多次打开 tkinter 窗口

Python - 过滤字典 JSON 响应以仅发回两个值或转换为字符串?

python - 关闭来自另一个线程的 "Python Requests"连接