0

我是 python 新手,正在尝试创建一个程序来测试一些对象创建方法。目前,我正在编写一个程序,该程序涉及创建对象,给它们一个唯一的数字变量,并将它们分配给一个列表以供将来参考。这是我为创建变量名而编写的内容:

def getRectangleName():
    rectName = list("Rectangle")
    SPAWNEDOBJECTLIST.append(len(SPAWNEDOBJECTLIST))
    rectName.append(str(len(SPAWNEDOBJECTLIST)))
    return rectName

然后将其传递给某些东西以将该字符串转换为变量名。我尝试了 eval(),发现由于某种原因这很糟糕,但无论如何它都不起作用,并尝试了一些解决方法无济于事。

我认为有很多游戏的屏幕上的角色数量不定。有没有一种既定的方法可以对这样的对象进行迭代?

对象本身有一个 X 和 Y,因此它们可以作为在屏幕上显示矩形的参考点(未来的想法是让每个对象自己移动,所以只需制作 X 和 Y 的列表来绘制矩形没用)。

编辑:问题是我不知道如何为每个对象赋予自己的变量以将其放在列表中以供将来参考。

Edit2:我认为我实际上没有提出正确的问题,也没有使用正确的术语。我需要能够在程序已经运行后动态创建无限数量的对象,并且能够单独引用它们。

4

4 回答 4

5

The problem is that I don't know how to give each object its own variable to put it on a list for future referencing.

Whenever you think you need variables you didn't type into your program, you're doing something wrong. You don't need to assign something to a variable to put it on a list:

x = [1, 2, 3]                 # Note how I don't assign 1, 2, or 3 to variables.
x.append(4)                   # 4 doesn't get a variable either.
x.append(make_a_rectangle())  # We create a rectangle and stick it on the list.
do_stuff_with(x[4])           # We pass the rectangle to a function.

x = []                            # New list.
for i in xrange(n):
    x.append(make_a_rectangle())  # This happens n times.
# At this point, we have n rectangles, none of them associated with their own
# variable, none of them with a name.

If you think you need names for things (and quite often, you don't really need the names), you can use a dict:

x = {}
x['foo'] = make_a_rectangle()
do_stuff_with(x['foo'])
于 2013-08-24T04:24:28.157 回答
1

将管理矩形的功能(访问、添加或删除它们)与成为矩形的想法结合起来并不是一个好主意。您永远不知道何时可能需要维护多个列表,或从无序列表更改为有组织的列表。

在您真的需要更多之前,请保持管理功能简单:使用内置列表或字典。如果您只关心订购,或者只需要知道您有一堆东西,请使用列表:

class Rectangle (object): 
    def __init__(self, top, bottom, left, right):
       self.Top = top
       self.Left = left
       self.Right = right
       self.Bottom = bottom

list_of_rects = [Rectangle(10,0,0,10), Rectangle(20, 10, 10 ,20)]

# how many rects?  
len(list_of_rects)
# result: 2


# where is this particular rect?
fred = Rectangle(30,20,20, 30)
list_of_rects.insert(fred, 1)
list_of_rects.index(fred)
# result: 1

#remove an item from the list:
list_of_rects.remove(fred)

#search the list:
right_of_5 = [rect for rect in list_of_rects if rect.Left > 5]

如果您出于某种原因需要访问各个矩形——“目标的矩形是什么”之类的——你有两个选择:

1)需要 rect 的代码只保留对它的引用:

class Goal(object):
   def __init__(self, rect):
      self.Rect = rect

goalrect =  Rectangle (0,0,20,20)
mygoal = Goal(goalrect)
list_of_rects.append(goalrect)

# now goalrect always knows about it's own rect, but the list can keep track of it too...

2)或者,使用字典:

named_rects = {}
named_rects['goal'] = Rectangle(0,0,20,20)

使用字典可以获得与使用列表相同的所有功能——添加、删除和查找——除了字典不保留顺序,因此你无法管理诸如优先级之类的事情:

# add to the dict:
named_rects['new_rect'] = Rectangle(90,90,95,95)

# remove
del named_rects['new_rect']

# find = is there a known key?
if 'new_rect' in named_rects: print new_rect

# search:
right_of_5 = [rect for rect in named_rects.items() if rect.Left > 5]

在某些情况下,您需要比普通的旧列表和字典更高级的东西——但总是先尝试免费的东西:)

于 2013-08-24T05:30:17.173 回答
0

If you really want to refer to your rectangle instances by name, I would suggest to keep a dictionary at class level. Something like this:

#! /usr/bin/python3

from threading import Lock
import random

class Rectangle:
    instances = {}
    lock = Lock ()

    @classmethod
    def forName (cls, name):
        return cls.instances [name] if name in cls.instances else None

    @classmethod
    def push (cls, inst):
        with cls.lock:
            name = None
            while not name or name in cls.instances:
                name = ''.join (random.choice ('abcdefghij') for i in range (16) )
            cls.instances [name] = inst
            return name

    def __init__ (self):
        self.name = Rectangle.push (self)


names = [Rectangle ().name for i in range (5) ]

for name in names:
    print (name, Rectangle.forName (name) )
于 2013-08-24T04:26:28.857 回答
0

如果您要动态创建变量并将它们添加到类实例中,请使用此

class MainClass:
    def __setattr__(self, name, value):
        self.__dict__[name] = value

def getRectangleNameGenerator(N = 10):
    X = 0
    while X <= N:
        X += 1
        yield "Rectangle" + str(X)
RectangleName = getRectangleNameGenerator()

ClassInstances = {next(RectangleName) : MainClass}
ClassInstances[next(RectangleName)] = MainClass

ClassInstances["Rectangle1"].Temp = 10
print ClassInstances["Rectangle1"].Temp

如果班级只有 X 和 Y,

class MainClass:
    X, Y = 0, 0

def getRectangleNameGenerator(N = 10):
    X = 0
    while X <= N:
        X += 1
        yield "Rectangle" + str(X)
RectangleName = getRectangleNameGenerator()

ClassInstances = {next(RectangleName) : MainClass}
ClassInstances[next(RectangleName)] = MainClass

ClassInstances["Rectangle1"].X = 11
print ClassInstances["Rectangle1"].X
于 2013-08-24T04:58:01.823 回答