我可以在Python 2.7中从文本文件创建对象名吗?

时间:2011-01-02 03:35:05

标签: python object python-2.x

我正在开发一个游戏项目。 我创建了一个对象Star(Object)。 我想动态地从文本文件中分配变量的名称。

如果我有一个文本文件:

Sol
Centauri
Vega

我希望程序使用文本文件中的变量名创建Star(Object)。我希望这个过程自动化,因为我希望创建数百颗星。 我可以手工编写代码:

Sol = Star(Sol)
Centauri = Star(Centauri)
Vega = Star(Vega)

但是有没有办法实现自动化呢?

基本上,我最终想要的是一个带有星星列表的元组,作为它们自己的对象。然后,当我进行游戏维护时,我可以迭代元组中的所有对象。

7 个答案:

答案 0 :(得分:4)

星号不应该是变量的名称。变量名称应反映使用变量的上下文,例如destinationStarhomeStar

星标的名称应该是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