使用函数创建 class 属性
Creating a class property using a function
我找到了这个奇幻名字生成器 here。
我正在尝试调整代码以满足我的目的。我想使用 class NPC
中的函数 name_gen
自动创建一个 NPC 名称。 NPC特征为:
class NPC:
def __init__(self, name, age, gender):
self.name = name_gen
self.age = 25
self.gender = M
我需要的名称生成器代码如下:
from random import randrange
def line_appender(file_path, target):
file = open(file_path, "r")
splitfile = file.read().splitlines()
for line in splitfile:
target.append(line)
def name_selector(target_list):
selected = target_list[randrange(len(target_list))]
return selected
def name_builder(first_name_list_path, last_name_list_path):
first_name_list = []
last_name_list = []
line_appender(first_name_list_path, first_name_list)
line_appender(last_name_list_path, last_name_list)
first_name_selected = name_selector(first_name_list)
last_name_selected = name_selector(last_name_list)
name = first_name_selected+" "+last_name_selected
return name
现在我认为我唯一还需要做的就是从 class NPC
中生成名称。我想做类似的事情:
def name_gen
if gender == "M":
name = name_builder("first_name_male.txt", "last_name.txt")
elif gender == "F":
name = name_builder("first_name_female.txt", "last_name.txt")
但我不明白如何让 name_gen
函数检查 class NPC
属性,
以便它生成所需的名称。
有人可以帮我吗?
编辑
感谢您提供所有解决方案!我对 Python 很陌生;为了测试 Samwises 解决方案,我尝试使用下面的代码 运行 它作为一个单独的脚本(以检查我是否会得到一个名字)。但是它不打印任何东西。我将其放入编辑中,因为我认为这可能是一个微不足道的问题。如果值得发布一个单独的问题,请告诉我:
import random
running = True
npc_input_messsage = "npc = NPC(25, 'M')"
class NameChooser:
def __init__(self, file_path):
with open(file_path) as f:
self._names = f.read().splitlines()
def choice(self):
return random.choice(self._names)
first_choosers = {
"M": NameChooser("first_name_male.txt"),
"F": NameChooser("first_name_female.txt"),
}
last_chooser = NameChooser("last_name.txt")
def name_gen(gender):
return f"{first_choosers[gender].choice()} {last_chooser.choice()}"
class NPC:
def __init__(self, age, gender):
self.name = name_gen(gender)
self.age = age
self.gender = gender
while running:
npc = input(npc_input_messsage)
# I'm entering npc = NPC(25, "M")
print(npc)
我认为您对 OOP 概念感到困惑。
首先,让我们编辑您的 class:
class NPC:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
看,我已经为属性分配了参数值。
现在让我们更改您的函数:
def name_gen(gender):
if gender == "M":
name = name_builder("first_name_male.txt", "last_name.txt")
elif gender == "F":
name = name_builder("first_name_female.txt", "last_name.txt")
return name
我在这里为您的函数添加了一个参数,因为您正在使用它的值。
现在让我们为您的 class.
创建一个实例
npc = NPC("Vishwas", 25, "M") # Instance of the class
print(name_gen(npc.gender)) # Print generated name
你的名字生成器有点 over-complicated IMO。我建议将所有文件读取和名称选择内容包装在一个简单的 class 中,这样您就可以定义一次,然后为每个名称列表实例化它。将文件读取部分放在 __init__
中意味着每个列表只执行一次,而不是每次需要选择名称时 re-reading 文件。
import random
class NameChooser:
def __init__(self, file_path):
with open(file_path) as f:
self._names = f.read().splitlines()
def choice(self):
return random.choice(self._names)
现在您可以定义三个 NameChooser
和一个从中选择的 name_gen
函数:
first_choosers = {
"M": NameChooser("first_name_male.txt"),
"F": NameChooser("first_name_female.txt"),
}
last_chooser = NameChooser("last_name.txt")
def name_gen(gender):
return f"{first_choosers[gender].choice()} {last_chooser.choice()}"
现在您可以定义一个 NPC
class,它将 age
和 gender
作为构造函数的参数,并使用 [=19= 选择一个随机名称]:
class NPC:
def __init__(self, age, gender):
self.name = name_gen(gender)
self.age = age
self.gender = gender
def __str__(self):
return f"{self.name} ({self.age}/{self.gender})"
npc = NPC(25, "M")
print(npc) # prints "Bob Small (25/M)"
实现自动发生的一种直接方法是使用 NPC.__init__()
方法简单地调用名称生成器。在下面的代码中,通过以下划线字符开头的名称使其成为 class 的私有方法。请注意,对它的调用必须等到它引用的所有实例属性都已分配值。
from random import randrange
class NPC:
def __init__(self, age, gender):
self.age = age
self.gender = gender
self.name = self._name_gen()
def _name_gen(self):
if self.gender == "M":
name = name_builder("first_name_male.txt", "last_name.txt")
elif self.gender == "F":
name = name_builder("first_name_female.txt", "last_name.txt")
return name
def line_appender(file_path, target):
file = open(file_path, "r")
splitfile = file.read().splitlines()
for line in splitfile:
target.append(line)
def name_selector(target_list):
selected = target_list[randrange(len(target_list))]
return selected
def name_builder(first_name_list_path, last_name_list_path):
first_name_list = []
last_name_list = []
line_appender(first_name_list_path, first_name_list)
line_appender(last_name_list_path, last_name_list)
first_name_selected = name_selector(first_name_list)
last_name_selected = name_selector(last_name_list)
name = first_name_selected+" "+last_name_selected
return name
if __name__ == '__main__':
npc1 = NPC(25, 'M')
print(f'{npc1.name!r}')
npc2 = NPC(21, 'F')
print(f'{npc2.name!r}')
我找到了这个奇幻名字生成器 here。
我正在尝试调整代码以满足我的目的。我想使用 class NPC
中的函数 name_gen
自动创建一个 NPC 名称。 NPC特征为:
class NPC:
def __init__(self, name, age, gender):
self.name = name_gen
self.age = 25
self.gender = M
我需要的名称生成器代码如下:
from random import randrange
def line_appender(file_path, target):
file = open(file_path, "r")
splitfile = file.read().splitlines()
for line in splitfile:
target.append(line)
def name_selector(target_list):
selected = target_list[randrange(len(target_list))]
return selected
def name_builder(first_name_list_path, last_name_list_path):
first_name_list = []
last_name_list = []
line_appender(first_name_list_path, first_name_list)
line_appender(last_name_list_path, last_name_list)
first_name_selected = name_selector(first_name_list)
last_name_selected = name_selector(last_name_list)
name = first_name_selected+" "+last_name_selected
return name
现在我认为我唯一还需要做的就是从 class NPC
中生成名称。我想做类似的事情:
def name_gen
if gender == "M":
name = name_builder("first_name_male.txt", "last_name.txt")
elif gender == "F":
name = name_builder("first_name_female.txt", "last_name.txt")
但我不明白如何让 name_gen
函数检查 class NPC
属性,
以便它生成所需的名称。
有人可以帮我吗?
编辑
感谢您提供所有解决方案!我对 Python 很陌生;为了测试 Samwises 解决方案,我尝试使用下面的代码 运行 它作为一个单独的脚本(以检查我是否会得到一个名字)。但是它不打印任何东西。我将其放入编辑中,因为我认为这可能是一个微不足道的问题。如果值得发布一个单独的问题,请告诉我:
import random
running = True
npc_input_messsage = "npc = NPC(25, 'M')"
class NameChooser:
def __init__(self, file_path):
with open(file_path) as f:
self._names = f.read().splitlines()
def choice(self):
return random.choice(self._names)
first_choosers = {
"M": NameChooser("first_name_male.txt"),
"F": NameChooser("first_name_female.txt"),
}
last_chooser = NameChooser("last_name.txt")
def name_gen(gender):
return f"{first_choosers[gender].choice()} {last_chooser.choice()}"
class NPC:
def __init__(self, age, gender):
self.name = name_gen(gender)
self.age = age
self.gender = gender
while running:
npc = input(npc_input_messsage)
# I'm entering npc = NPC(25, "M")
print(npc)
我认为您对 OOP 概念感到困惑。
首先,让我们编辑您的 class:
class NPC:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
看,我已经为属性分配了参数值。 现在让我们更改您的函数:
def name_gen(gender):
if gender == "M":
name = name_builder("first_name_male.txt", "last_name.txt")
elif gender == "F":
name = name_builder("first_name_female.txt", "last_name.txt")
return name
我在这里为您的函数添加了一个参数,因为您正在使用它的值。 现在让我们为您的 class.
创建一个实例npc = NPC("Vishwas", 25, "M") # Instance of the class
print(name_gen(npc.gender)) # Print generated name
你的名字生成器有点 over-complicated IMO。我建议将所有文件读取和名称选择内容包装在一个简单的 class 中,这样您就可以定义一次,然后为每个名称列表实例化它。将文件读取部分放在 __init__
中意味着每个列表只执行一次,而不是每次需要选择名称时 re-reading 文件。
import random
class NameChooser:
def __init__(self, file_path):
with open(file_path) as f:
self._names = f.read().splitlines()
def choice(self):
return random.choice(self._names)
现在您可以定义三个 NameChooser
和一个从中选择的 name_gen
函数:
first_choosers = {
"M": NameChooser("first_name_male.txt"),
"F": NameChooser("first_name_female.txt"),
}
last_chooser = NameChooser("last_name.txt")
def name_gen(gender):
return f"{first_choosers[gender].choice()} {last_chooser.choice()}"
现在您可以定义一个 NPC
class,它将 age
和 gender
作为构造函数的参数,并使用 [=19= 选择一个随机名称]:
class NPC:
def __init__(self, age, gender):
self.name = name_gen(gender)
self.age = age
self.gender = gender
def __str__(self):
return f"{self.name} ({self.age}/{self.gender})"
npc = NPC(25, "M")
print(npc) # prints "Bob Small (25/M)"
实现自动发生的一种直接方法是使用 NPC.__init__()
方法简单地调用名称生成器。在下面的代码中,通过以下划线字符开头的名称使其成为 class 的私有方法。请注意,对它的调用必须等到它引用的所有实例属性都已分配值。
from random import randrange
class NPC:
def __init__(self, age, gender):
self.age = age
self.gender = gender
self.name = self._name_gen()
def _name_gen(self):
if self.gender == "M":
name = name_builder("first_name_male.txt", "last_name.txt")
elif self.gender == "F":
name = name_builder("first_name_female.txt", "last_name.txt")
return name
def line_appender(file_path, target):
file = open(file_path, "r")
splitfile = file.read().splitlines()
for line in splitfile:
target.append(line)
def name_selector(target_list):
selected = target_list[randrange(len(target_list))]
return selected
def name_builder(first_name_list_path, last_name_list_path):
first_name_list = []
last_name_list = []
line_appender(first_name_list_path, first_name_list)
line_appender(last_name_list_path, last_name_list)
first_name_selected = name_selector(first_name_list)
last_name_selected = name_selector(last_name_list)
name = first_name_selected+" "+last_name_selected
return name
if __name__ == '__main__':
npc1 = NPC(25, 'M')
print(f'{npc1.name!r}')
npc2 = NPC(21, 'F')
print(f'{npc2.name!r}')