使用外部函数创建总是返回相同值的类对象的属性



在制作一款简单的足球游戏的过程中,我遇到了一个我以前没有遇到过的类对象初始化问题,并且找不到一个好的解决方案。正如在代码底部的main方法中所看到的,迭代地创建Player()的新实例总是共享相同的实例属性值,尽管这些值在init中被初始化。我知道这必须与使用外部方法作为默认值有关,但我不明白为什么这些值不会是唯一的,因为它们不是类属性,它们是实例属性……对吧?

# import dependencies
import random
from position import Position

# external methods
def file_to_list(url: str) -> list[str]:
f = open(url, 'r')
all_lines = []
for line in f:
stripped_line = (line.strip())
all_lines.append(stripped_line)
f.close()
return all_lines

def get_random_name() -> str:
first_names: list[str] = file_to_list("assets/boys_names.txt")
last_names: list[str] = file_to_list("assets/last_names.txt")
return random.choice(first_names) + ' ' + random.choice(last_names)

def get_random_age() -> int:
return random.randint(17, 37)

def get_random_nationality() -> str:
dice: int = random.randint(1, 3)
if dice == 1:
return "British"
elif dice == 2:
return random.choice(
["French", "Spanish", "Italian", "Brazilian", "Portuguese", "Irish", "Danish", "Dutch", "German", "Belgian",
"Argentinian"])
else:
nationalities: list[str] = file_to_list("assets/nationalities.txt")
return random.choice(nationalities)

def get_random_score() -> float:
base: float = float(random.randint(1, 10))
if base == float(10):
return base
else:
decimal: float = random.uniform(0, 1)
return round(base + decimal, 1)

# class definition
class Player:
def __init__(self, name: str = get_random_name(), position: Position = None, age: int = get_random_age(),
nationality: str = get_random_nationality(), attack: int = get_random_score(),
defense: int = get_random_score()):
self.__name: str = name
self.__position: Position = position
self.__age: int = age
self.__nationality: str = nationality
self.__attack: float = attack
self.__defense: float = defense
self.__skill: int = int(((self.__attack + self.__defense) / 2) * 10)
@property
def name(self):
return self.__name
@property
def position(self):
return self.__position
@property
def age(self):
return self.__age
@property
def nationality(self):
return self.__nationality
@property
def attack(self):
return self.__attack
@property
def defense(self):
return self.__defense
@property
def skill(self):
return self.__skill
def __str__(self) -> str:
print("Name: " + self.__name)
if not self.__position:
print("Position not set.")
else:
print("Position: " + self.__position.name)
print("Age: " + str(self.__age))
print("Nationality: " + self.__nationality)
print("Skill: " + str(self.__skill))
print("Attack: " + str(self.__attack))
return "Defense: " + str(self.__defense)

if __name__ == "__main__":
player_list: list[Player] = []
for i in range(3):
new: Player = Player() #if i pass in a value it will not be shared.
player_list.append(new)
for p in player_list:
print(p)

每次创建玩家时,他们共享所有未传入的相同值。示例输出:

Name: Royal Vega
Position not set.
Age: 36
Nationality: British
Skill: 48
Attack: 1.2
Defense: 8.5
Name: Royal Vega
Position not set.
Age: 36
Nationality: British
Skill: 48
Attack: 1.2
Defense: 8.5
Name: Royal Vega
Position not set.
Age: 36
Nationality: British
Skill: 48
Attack: 1.2
Defense: 8.5

相反,预期的输出将返回3个随机年龄,姓名和技能的唯一对象,如上述代码所示。

"在Python函数中参数可以有默认值。这些默认值是在定义函数时执行的表达式,即只执行一次。每次调用函数时都会使用相同的默认值,因此修改它将对后续的每次调用产生影响。这会产生一些非常令人困惑的bug。">

您需要将默认值设置为None,并在构造函数中添加if语句,例如:

if name == None:
self.__name = get_random_name()

相关内容

  • 没有找到相关文章

最新更新