0

我正在创建一个运动队数据库,其中存储有关运动队的信息。我在其中一种方法中遇到的问题之一是无法防止同一对象两次附加到列表中。我不希望用户两次添加相同的信息,但我不完全确定如何解决此问题。

我在 Python Tkinter 下工作来创建这个程序。

import tkinter as tk
from tkinter import ttk
from tkinter import messagebox


allTeamlist = []



class Team: 

 def __init__(self, team, coach):
   self.team = team
   self.coach = coach
   self.studentsinTeam = []


class MainScreen:
 def __init__(self):

  self.mainscreen = tk.Tk()
  self.mainscreen.title("GUI")
  self.mainscreen.geometry("700x400")

#####Team Buttons##########
  heading3 = tk.Label(self.mainscreen, text= "Team", foreground = "Red", font=("Arial", 10))
  heading3.pack()

  button6 = tk.Button(self.mainscreen, text = "Add New Team", command= self.ShowScreen6)
  button6.pack()

 def OpenWindow(self):
  tk.mainloop()

 def ShowScreen6(self):
  self.mainscreen.destroy()
  screen6 = AddTeamScreen()

class AddTeamScreen:

 def __init__(self):
  self.Tscreen1 = tk.Tk()
  self.Tscreen1.title("Add Team")
  self.Tscreen1.geometry("700x400")

  self.getTeam = tk.StringVar()
  self.getCoach = tk.StringVar()

  self.teamlabel = tk.Label(self.Tscreen1, text = "Add a new Team")
  self.teamlabel.pack()

  self.teamentry = tk.Entry(self.Tscreen1, textvariable= self.getTeam)
  self.teamentry.pack()

  self.coachlabel = tk.Label(self.Tscreen1, text= "Coach")
  self.coachlabel.pack()

  self.coachentry = tk.Entry(self.Tscreen1, textvariable = self.getCoach)
  self.coachentry.pack()

  self.addbutton = tk.Button(self.Tscreen1, text = "Add Team", command = self.addingteammethod)
  self.addbutton.pack()

 def addingteammethod(self):

  addTeam = self.getTeam.get()
  addCoach = self.getCoach.get()

  newTeamtoAdd = Team(addTeam, addCoach)

  if newTeamtoAdd in allTeamlist: 
   messagebox.showerror("Error", "Exists")

  elif newTeamtoAdd not in allTeamlist:
   allTeamlist.append(newTeamtoAdd)
   messagebox.showinfo("SUCCESS", "ADDED")
   print(allTeamlist)

mainscreen = MainScreen()
mainscreen.OpenWindow()

我是新的 OOP 和 Tkinter 编程,所以我还在学习!如何防止这种情况发生?

4

1 回答 1

0

看看这个例子:

class Team:

    def __init__(self, name, coach):
        self.name = name
        self.coach = coach

team1 = Team("The Teamsters", "Coachy McCoachFace")
team2 = Team("The Teamsters", "Coachy McCoachFace")
teams = [team1, team2]

print(f"Do team1 and team2 have the same identity?: {id(team1)==id(team2)}")
print(f"id(team1): {id(team1)}")
print(f"id(team2): {id(team2)}")

print(f"Are team1 and team2 equivalent?: {team1==team2}")

is_new_team_in_list = Team("The Teamsters", "Coachy McCoachFace") in teams
print(f"Is a new team with the same content in the list?: {is_new_team_in_list}")

输出:

Do team1 and team2 have the same identity?: False
id(team1): 46804752
id(team2): 47020080
Are team1 and team2 equivalent?: False
Is a new team with the same content in the list?: False

第一个打印语句检查两个团队对象是否具有相同的标识(如果它们是内存中的相同对象 - 两个变量team1team2绑定到相同的Team对象)。这是错误的。

接下来的两个打印语句显示了两个团队对象的 id - 如您所见,它们是不同的 - 因此,存在两个具有相同内容的单独团队对象。

下一个 print 语句确定两个团队对象是否共享相同的内容(如果它们是等价的)——至少看起来是这样,因为我们使用==. 然而,由于我们没有__eq__为我们的类实现魔法方法Team,默认行为会退回到身份比较,我们已经知道这是错误的。

最后,最后一条 print 语句检查是否会在使用in. 由于与上述相同的原因,结果再次为假。

一种解决方案是__eq__为您的 Team 类实施:

class Team:

    def __init__(self, name, coach):
        self.name = name
        self.coach = coach

    def __eq__(self, other):
        if isinstance(other, Team):
            return self.name == other.name and self.coach == other.coach
        return False

team1 = Team("The Teamsters", "Coachy McCoachFace")
team2 = Team("The Teamsters", "Coachy McCoachFace")
teams = [team1, team2]

print(f"Do team1 and team2 have the same identity?: {id(team1)==id(team2)}")
print(f"id(team1): {id(team1)}")
print(f"id(team2): {id(team2)}")

print(f"Are team1 and team2 equivalent?: {team1==team2}")

is_new_team_in_list = Team("The Teamsters", "Coachy McCoachFace") in teams
print(f"Is a new team with the same content in the list?: {is_new_team_in_list}")

输出:

Do team1 and team2 have the same identity?: False
id(team1): 46016240
id(team2): 46936048
Are team1 and team2 equivalent?: True
Is a new team with the same content in the list?: True

现在你得到了想要的行为。请注意,Team 对象的身份仍然不同,这是意料之中的。您还可以更改__eq__方法的行为以满足您的需要。例如,如果只有名称匹配,您可能希望将两个团队视为相同。

于 2019-10-06T13:09:40.710 回答