Python类间数据关联问题:无法正确传递与关联数据
问题描述
我打算开发一个Python程序,用列表、类、对象和嵌套循环实现数据关联,但不知道怎么合理架构程序,实现类内部方法的数据有效传递。5年前用C++时遇到过类似问题,当时为了模块化获取位图数据用了指针技巧,养成了把函数调用作为另一个函数参数的不良编码习惯,我知道这类代码不规范。
当前项目要实现游戏名称与对应平台的关联,展示游戏及其适配平台的列表,参考C#示例改用Python实现。我尝试把Platform对象添加到Game对象的availability列表(比如把Xbox和PlayStation加入《Secret Weapons Over Normandy》的列表),并打印这些平台的名称。
主程序需要嵌套循环,遍历游戏及其平台列表并打印平台名称,也能反向按平台列出对应游戏。虽然把游戏标题作为Platform类对象的列表更简单,但游戏需要独立存储自身数据,所以必须定义为类。
请问怎么实现不同类对象及其数据的关联?有没有比列表更合适的数据结构?
示例1
class Game: name = "" availability = [] def __init__(self, InputName): self.availability = [] print ("created, " + InputName) name = InputName def ShowAvailability(self): return (iter(self.availability)) class Platform: name = "" def __init__(self, InputName): print "created, " + InputName name = InputName def GrabName(): return name # Game titles SecretWeapons = Game("Secret Weapons Over Normandy") Halo = Game("Halo Combat Evolved") DeathStranding = Game("Death Stranding") # Platforms Xbox = Platform("Xbox") PlayStation = Platform("Playstation") SecretWeapons.availability.append(Xbox) SecretWeapons.availability.append(PlayStation) for i in SecretWeapons.ShowAvailability(): print (i.GrabName)
示例2(错误实现方式)
class Game: name = "" availability = [] def __init__(self, InputName): self.availability = [] print ("created, " + InputName) name = InputName # Prepare to fail... def ShowAvailability(self): return self.availability class Platform: name = "" AvailableGames = [] def __init__(self, InputName): print "created, " + InputName name = InputName def GrabName(): return name # Game titles SecretWeapons = Game("Secret Weapons Over Normandy") Halo = Game("Halo Combat Evolved") DeathStranding = Game("Death Stranding") # Platforms Xbox = Platform("Xbox") PlayStation = Platform("Playstation") SecretWeapons.availability.append(Xbox) SecretWeapons.availability.append(PlayStation) mylist = SecretWeapons.ShowAvailability() # OOOOFFFFFFF! It won't print the platforms for the game. for element in mylist: print(element)
示例3(尝试传递字符串的无效方式)
SecretWeapons.availability.append(Xbox.name) SecretWeapons.availability.append(PlayStation.name) SecretWeapons.ShowAvailability()
示例4(无构造函数的类方法)
class Game: name = "" availability = [] def ShowAvailability(self): for mystuff in self.availability: print(mystuff)
解决方案
1. 修正类的基础问题
你的代码核心问题是误用类属性、未正确定义实例方法:
- Python中,类内直接定义的
name = ""是类属性,所有实例共享;要存储每个实例的独有数据,必须在__init__里用self.name = 输入值定义实例属性。 - 类的实例方法必须以
self作为第一个参数,否则无法访问当前实例的属性(比如GrabName方法需要改为def GrabName(self):)。
修正后的基础类:
class Game: def __init__(self, name): self.name = name # 实例属性存储游戏名称 self.availability = [] # 实例属性存储适配平台对象列表 print(f"created, {name}") def show_availability(self): return self.availability class Platform: def __init__(self, name): self.name = name # 实例属性存储平台名称 self.available_games = [] # 实例属性存储对应游戏对象列表 print(f"created, {name}") def get_name(self): return self.name
2. 实现双向对象关联
为了同时支持“按游戏查平台”和“按平台查游戏”,可以写一个辅助方法完成双向绑定,避免重复关联:
def bind_game_platform(game, platform): if platform not in game.availability: game.availability.append(platform) if game not in platform.available_games: platform.available_games.append(game) # 创建实例 secret_weapons = Game("Secret Weapons Over Normandy") halo = Game("Halo Combat Evolved") death_stranding = Game("Death Stranding") xbox = Platform("Xbox") playstation = Platform("Playstation") # 绑定关联关系 bind_game_platform(secret_weapons, xbox) bind_game_platform(secret_weapons, playstation) bind_game_platform(halo, xbox) bind_game_platform(death_stranding, playstation)
3. 遍历展示数据
按游戏展示适配平台
games = [secret_weapons, halo, death_stranding] for game in games: print(f"游戏《{game.name}》的适配平台:") for platform in game.show_availability(): print(f"- {platform.get_name()}")
按平台展示支持的游戏
platforms = [xbox, playstation] for platform in platforms: print(f"平台{platform.get_name()}支持的游戏:") for game in platform.available_games: print(f"- 《{game.name}》")
4. 更合适的数据结构推荐
- 字典:如果需要快速通过名称查找对象(比如根据游戏名找对应平台),可以用字典映射:
game_dict = {game.name: game for game in games} platform_dict = {platform.name: platform for platform in platforms} - 集合:如果需要避免重复关联(同一个平台不能重复添加到同一个游戏),可以用集合替代列表,集合会自动去重,但元素必须可哈希(自定义类默认满足)。若需要保留添加顺序,Python 3.7+的字典或第三方库
collections.OrderedSet可满足需求。
内容的提问来源于stack exchange,提问作者Jeff
相关产品推荐
相关产品推荐

