如何返回自定义类player_result对象而非字符串(不可修改类)
自定义类对象返回与显示问题
问题说明
- 要求返回
player_result类的对象列表以通过测试,但当前只能返回该类的字符串表示列表,且禁止修改player_result类的代码 - 当前存在两种异常输出:
- 输出内容为类对象的字符串表示列表(而非对象本身)
- 直接输出对象列表时,仅显示内存地址(无法看到对象属性)
- 期望输出:返回对象列表的同时,打印列表时能显示对象的完整属性(如
player_result(name='Erik', points=2.5, resistance_points=4.0, sonnenborn_berger=3.00, black=2))
原代码
# DON'T MODIFY THIS CLASS import numpy as np import pandas as pd class player_result: def __init__(self, name: str, points: float, resistance_points: float, sonnenborn_berger: float, black: int): self.name = name self.points = points self.resistance_points = resistance_points self.sonnenborn_berger = sonnenborn_berger self.black = black def __str__(self): return 'player_result(name=\'' + self.name + '\', points=' + str(self.points) + ', resistance_points=' + \ str(self.resistance_points) + ', sonnenborn_berger=' + str(self.sonnenborn_berger) + \ ', black=' + str(self.black) + ')' def __eq__(self, other): return self.name == other.name and self.points == other.points and \ self.resistance_points == other.resistance_points and \ self.sonnenborn_berger == other.sonnenborn_berger and self.black == other.black def determine_output(input: str): create_player_and_round_obj(input) def create_player_and_round_obj(input_string): player_obj = {} rounds_obj = {} curr_round = 0 round_list = [] for line in input_string.splitlines(): if " " in line: round_list = line.split(" ") rounds_obj[curr_round] = round_list curr_round += 1 elif len(line) < 1: continue else: player_obj[line] = {'pt': 0.0, 'rp': 0.0, 'sb': 0.0, 'b': 0.0} calculate_reg_points(player_obj, rounds_obj) def calculate_reg_points(player_obj, rounds_obj): for results in rounds_obj.values(): indexed_result = np.array(results) if indexed_result[2] == '1': # 胜负积分 player_obj[results[0]]['pt'] += 1.0 # 执黑次数 player_obj[results[1]]['b'] += 1.0 elif indexed_result[2] == '0': # 胜负积分 player_obj[results[1]]['pt'] += 1.0 # 执黑次数 player_obj[results[1]]['b'] += 1.0 elif indexed_result[2] == '0.5': # 胜负积分 player_obj[results[0]]['pt'] += 0.5 player_obj[results[1]]['pt'] += 0.5 # 执黑次数 player_obj[results[1]]['b'] += 1.0 calculate_rp(player_obj, rounds_obj) def calculate_rp(player_obj, rounds_obj): # 构建对手字典 opponents = {} for k, v in rounds_obj.items(): if v[0] not in opponents.keys(): opponents[v[0]] = [] # 为每个玩家添加所有对手 for player in opponents.keys(): for rnd in rounds_obj.values(): if player in rnd: for item in rnd: not_it = [player, '1', '0', '0.5'] if item not in not_it: opponents[player] += [item] # 计算对手积分总和(rp) for player_name, points_dict in player_obj.items(): for playr, opp_list in opponents.items(): if player_name == playr: for opp in opp_list: player_obj[player_name]["rp"] += player_obj[opp]["pt"] calculate_sb(player_obj, rounds_obj) def calculate_sb(player_obj, rounds_obj): # 计算索恩伯恩-伯格积分(sb) for results in rounds_obj.values(): indexed_result = np.array(results) if indexed_result[2] == '1': player_obj[results[0]]['sb'] += 1.0 * player_obj[results[1]]['pt'] elif indexed_result[2] == '0': player_obj[results[1]]['sb'] += 1.0 * player_obj[results[0]]['pt'] elif indexed_result[2] == '0.5': player_obj[results[0]]['sb'] += 0.5 * player_obj[results[1]]['pt'] player_obj[results[1]]['sb'] += 0.5 * player_obj[results[0]]['pt'] sort_players(player_obj) def sort_players(player_obj): df = pd.DataFrame.from_dict(player_obj, orient='index') df = df.sort_values(by=['pt', 'rp', 'sb', 'b'], ascending=[ False, False, False, False]) results = df.to_records() final_list = [] for result in results: h = player_result(name=result[0], points=result[1], resistance_points=result[2], sonnenborn_berger=result[3], black=result[4]) final_list.append(h) print(final_list) return final_list
解决方案
1. 修正函数返回逻辑,确保返回对象列表
当前代码的函数调用链未传递返回值,导致determine_output无法返回最终的对象列表。需修改以下函数:
- 修改
determine_output,让它返回结果:
def determine_output(input: str): return create_player_and_round_obj(input)
- 修改
create_player_and_round_obj,返回calculate_reg_points的结果:
def create_player_and_round_obj(input_string): # 原逻辑不变 return calculate_reg_points(player_obj, rounds_obj)
- 修改
calculate_reg_points、calculate_rp、calculate_sb,依次传递返回值:
def calculate_reg_points(player_obj, rounds_obj): # 原逻辑不变 return calculate_rp(player_obj, rounds_obj) def calculate_rp(player_obj, rounds_obj): # 原逻辑不变 return calculate_sb(player_obj, rounds_obj) def calculate_sb(player_obj, rounds_obj): # 原逻辑不变 return sort_players(player_obj)
修改后,调用determine_output就能直接获取player_result对象列表,满足测试要求。
2. 解决对象列表打印显示内存地址的问题
player_result类已实现__str__方法,但列表打印时会调用元素的__repr__方法。由于不能修改原类代码,可通过动态添加__repr__方法解决:
在导入类之后添加以下代码:
player_result.__repr__ = player_result.__str__
这样打印对象列表时,会自动显示和__str__一致的格式,符合期望输出。
3. 修正black属性的类型问题
期望输出中black是整数,但当前代码中player_obj的'b'初始值为0.0,导致最终black参数为浮点数(如2.0)。需要修改:
- 在
create_player_and_round_obj中,将'b'的初始值设为整数:
player_obj[line] = {'pt': 0.0, 'rp': 0.0, 'sb': 0.0, 'b': 0}
- 在
calculate_reg_points中,累加整数而非浮点数:
# 所有修改'b'的地方都改为加1 player_obj[results[1]]['b'] += 1
这样创建player_result对象时,black参数就是整数,匹配期望输出格式。
内容的提问来源于stack exchange,提问作者Cole Eckelberry
相关产品推荐
相关产品推荐

