我正在开发一个游戏项目。 我创建了一个对象Star(Object)。 我想动态地从文本文件中分配变量的名称。
如果我有一个文本文件:
Sol
Centauri
Vega
我希望程序使用文本文件中的变量名创建Star(Object)。我希望这个过程自动化,因为我希望创建数百颗星。 我可以手工编写代码:
Sol = Star(Sol)
Centauri = Star(Centauri)
Vega = Star(Vega)
但是有没有办法实现自动化呢?
基本上,我最终想要的是一个带有星星列表的元组,作为它们自己的对象。然后,当我进行游戏维护时,我可以迭代元组中的所有对象。
答案 0 :(得分:4)
星号不应该是变量的名称。变量名称应反映使用变量的上下文,例如destinationStar
或homeStar
。
星标的名称应该是Star
对象的属性,可以通过Star.name
访问:
class Star(object):
"""Keeps track of a star."""
def __init__(self, starName):
self.name = starName
# other methods...
def read_stars(filename):
# oversimplified:
stars = {}
starfile = open(filename, "r")
for line in starfile:
words = line.split()
if len(words) == 2 and words[0] == 'star':
name = words[1]
stars[name] = Star(name)
return stars
通过存储在字典中,您可以使用Star
搜索特定的stars[name]
,或者使用for s in stars.values()
遍历所有星标。
答案 1 :(得分:1)
I want to assign the name of the variables, dynamically
这是一个很好的迹象,表明你的设计是完全错误的。
很难确切知道你的设计是什么,但我猜你想要使用字典。
答案 2 :(得分:1)
class BadStar(Exception): pass
class Star(object):
def __init__(self, name, mass, mag, color, x, y, z):
self.name = name
self.mass = float(mass)
self.mag = float(mag)
self.color = color
self.pos = (float(x),float(y),float(z))
@classmethod
def fromstr(cls, s):
"Alternate constructor from string"
stardata = [i.strip() for i in s.split(',')]
if len(stardata)==7:
return cls(*stardata)
else:
raise BadStar("wrong number of arguments in string constructor")
def __str__(self):
x,y,z = self.pos
return "{0} is at ({1}, {2}, {3})".format(self.name, x, y, z)
class StarIndex(dict):
def load(self, fname):
"Load stars from text file"
with open(fname, "r") as f:
for line in f:
line = line.split('#')[0] # discard comments
line = line.strip() # kill excess whitespace
if len(line): # anything left?
try:
star = Star.fromstr(line)
self[star.name] = star
except BadStar:
pass # discard lines that don't parse
return self
以及一些示例数据:
# Name, Mass, Absolute Magnitude, Color, x, y, z
#
# Mass is kg
# Color is rgb hex
# x, y, z are lightyears from earth, with +x to galactic center and +z to galactic north
Sol, 2.0e30, 4.67, 0xff88ee, 0.0, 0.0, 0.0
Alpha Centauri A, 2.2e30, 4.35, 0xfff5f1, -1.676, -1.360, -3.835
然后您可以加载您的文件,如:
s = StarIndex().load("stars.txt")
和
print s["Sol"]
结果
Sol is at (0.0, 0.0, 0.0)
答案 3 :(得分:0)
你的问题不明确。你使用语法'Star(Centauri)'会让你感到阴霾,它在Python中意味着你要创建一个继承自Centauri的名为'Star'的类。我想你想要的可能是一个创造不同星星的工厂对象,但是你没有说明星星可能会有什么不同。据推测,不同之处在于位置,但您没有说明如何处理。
根据猜测,最好的选择可能是将您的星型配置放在YAML文件中并使用pyYAML加载它,这会返回一个准备好的Python数据结构。
答案 4 :(得分:0)
def makeStar(starName):
globals()[starName] = Star(globals()[starName])
makeStar("Sol")
与
相同Sol = Star(Sol)
除了“Sol”可以替换为任何字符串(例如从该文件读入的值)。
此外,您可能想要重新考虑制作这些全局变量 - 它会阻止您在需要时迭代所有星星,并且可能导致命名冲突。如果你想让它们在字典中,那么只需用你的字典名称替换“globals()”。
答案 5 :(得分:0)
你可能应该使用字典。有可能创建dinamic变量名,但它没有任何意义,因为要访问那么你无论如何都需要间接引用。
stars = {}
with open("stars.txt") as stars_file:
for star_name in stars_file:
star_name = star_name.strip()
stars[star_name] = Star(star_name)
答案 6 :(得分:-1)
您可以使用types模块在运行时创建类对象:
import types
def make_class(name):
cls = types.ClassType(name, (), {})
return cls
cls = make_class("Star")
obj = cls()
在上面的示例中,cls成为您的class Star