【问题标题】:How can I create an indefinite iterations of objects in python?如何在 python 中创建对象的无限迭代?
【发布时间】:2013-08-27 05:07:16
【问题描述】:

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

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

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

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

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

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

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

【问题讨论】:

  • 您是否需要按名称寻址每个对象,例如,可以只使用一个对象列表来代替?
  • 使用dict 将矩形名称映射到矩形对象有什么问题?
  • 另外,您可能希望将您的函数称为其他名称。如果我调用一个名为 getRectangleNumber 的函数,我希望返回一个数字,而不是 list。
  • 您能举一个使用矩形对象的代码示例吗?您发布的代码需要更多上下文。
  • 通过这个:learnpythonthehardway.org 遇到困难时提出问题。

标签: python list class oop object


【解决方案1】:

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

每当您认为需要未在程序中键入的变量时,您就做错了。您无需将某些内容分配给变量即可将其放在列表中:

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.

如果你认为你需要给事物起名字(而且很多时候,你并不真的需要名字),你可以使用 dict:

x = {}
x['foo'] = make_a_rectangle()
do_stuff_with(x['foo'])

【讨论】:

    【解决方案2】:

    如果您真的想按名称引用矩形实例,我建议您在类级别保留字典。像这样的:

    #! /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) )
    

    【讨论】:

      【解决方案3】:

      如果你想动态创建变量并将它们添加到类实例中,使用这个

      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
      

      【讨论】:

        【解决方案4】:

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

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

        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)
        

        使用字典可以获得与使用列表相同的所有功能 -- 添加、删除和查找 -- except 字典不保留顺序,因此您无法管理事物喜欢优先级:

        # 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]
        

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

        【讨论】:

          猜你喜欢
          • 2017-09-29
          • 1970-01-01
          • 2020-02-12
          • 2019-02-26
          • 1970-01-01
          • 1970-01-01
          • 2014-08-05
          • 2020-08-06
          • 1970-01-01
          相关资源
          最近更新 更多