【问题标题】:Python - Call an object from a list of objectsPython - 从对象列表中调用一个对象
【发布时间】:2012-04-30 15:58:09
【问题描述】:

我有一个类,我希望能够创建该类的多个对象并将它们放在一个数组中。我是这样做的:

    rooms = []
    rooms.append(Object1())
    ...
    rooms.append(Object4())

然后我有一个函数字典,我想将对象传递给函数。但是,我遇到了一些问题。例如,我有一个字典:

    dict = {'look': CallLook(rooms[i])}

不过,我可以将它传递给函数;在函数中,如果我尝试调用对象方法,它会给我带来问题

    def CallLook(current_room)
       current_room.examine()

我确信必须有更好的方法来做我想做的事情,但我是 Python 新手,我还没有看到一个关于如何做到这一点的干净示例。任何人都有实现要传递给函数的对象列表的好方法吗?所有对象都包含检查方法,但它们是不同类的对象。 (对不起,我之前没有这么说)

具体错误状态:TypeError: 'NoneType' object is not callable

【问题讨论】:

  • 与其让我们猜测您可能遇到的问题,不如向我们解释问题会更容易。更好的是,发布错误消息或不良行为。
  • 假设Object1() 等都具有.examine 方法,这看起来很好。这些实例是否都应该是不同的类?
  • 如果您收到该错误,则该代码不准确。
  • 在您的代码中,您正在创建不同类的不同对象。
  • dict 的目的是什么。附言。不要使用 dict 作为变量名,因为它会影响内置的 dict

标签: python function object dictionary


【解决方案1】:

假设您有一个 Room 类,创建实例列表的常用方法是使用这样的列表推导

rooms = [Room() for i in range(num_rooms)]

【讨论】:

    【解决方案2】:

    假设您没有基本问题(例如语法错误,因为您粘贴的代码不是有效的 Python),此示例将向您展示如何做您想做的事情:

    >>> class Foo():
    ...    def hello(self):
    ...        return 'hello'
    ...
    >>> r = [Foo(),Foo(),Foo()]
    >>> def call_method(obj):
    ...    return obj.hello()
    ...
    >>> call_method(r[1])
    'hello'
    

    【讨论】:

      【解决方案3】:

      我认为有些事情你可能不明白:

      dict = {'look': CallLook(rooms[i])}
      

      这将创建一个只有一个条目的dict:一个键'look',以及一个值,该值是在该语句处对CallLook(rooms[i]) 求值的结果。然后它还使用名称 dict 来存储此对象,因此您不能再将 dict 用作该上下文中的构造函数。

      现在,您收到的错误告诉我们,rooms[i] is None 在程序中的那个时候。

      您不需要CallLook(也称为非标准名称)- 您可以只使用表达式rooms[i].examine(),或者如果您想稍后评估调用rooms[i].examine

      你可能根本不需要字典。

      【讨论】:

      • 对不起,我用一个条目制作了字典作为示例。我是 python 新手,我对适当的标准知之甚少。我需要 dict 因为我有一个输入函数,它接收来自用户的字符串命令并将它们与函数相关联
      • @user1343005 您的 dict 没有将键与函数关联。现在,它正在将您的键与函数调用生成的值相关联。
      • 哦,好吧,这是有道理的。但是,您如何将它与函数正确关联?
      • @user1343005 只需将函数存储在字典中即可。在这种情况下,您可能希望存储未绑定的方法(即从类中获取的方法),并在特定实例上调用它。
      【解决方案4】:

      我不确定您的要求,但您可以使用 dict 来存储一个类的多个对象。 也许这会有所帮助,

      >>> class c1():
      ...     print "hi"
      ...     
      hi
      >>> c = c1()
      >>> c
      <__main__.c1 instance at 0x032165F8>
      
      >>> d ={}
      >>> for i in range (10):
      ...     d[i] = c1()
      ...     
      >>> d[0]
      <__main__.c1 instance at 0x032166E8>
      >>> d[1]
      <__main__.c1 instance at 0x032164B8>
      >>> 
      

      它将创建一个 c1 类的对象并将其存储在 dict 中。显然,在这种情况下,您可以使用 list 而不是 dict。

      【讨论】:

        【解决方案5】:

        这不是必须的,但在某些情况下,使用 hasattr() 很好...getattr() 是从对象中获取属性的另一种方法...

        所以:

        rooms = [Obj1(),Obj2(),Obj3()]
        
        
        if hasattr(rooms[i], 'examine'):#First check if our object has selected function or attribute...
            getattr(rooms[i], 'examine') #that will just evaluate the function do not call it, and equals to Obj1().examine
            getattr(rooms[i], 'examine')() # By adding () to the end of getattr function, we evalute and then call the function...
        

        您也可以将参数传递给examine 函数,例如:

        getattr(rooms[i], 'examine')(param1, param2)
        

        【讨论】:

          【解决方案6】:

          谁有一个很好的方法来实现要传递给函数的对象列表?所有对象都包含检查方法,但它们是不同类的对象。 (对不起,我之前没有这么说)

          这是 Python 的普通鸭子类型。

          class Room:
              def __init__(self, name):
                  self.name = name
              def examine(self):
                  return "This %s looks clean!" % self.name
          
          class Furniture:
              def __init__(self, name):
                  self.name = name
              def examine(self):
                  return "This %s looks comfortable..." % self.name
          
          def examination(l):
              for item in l:
                  print item.examine()
          
          list_of_objects = [ Room("Living Room"), Furniture("Couch"), 
                              Room("Restrooms"), Furniture("Bed") ]
          examination(list_of_objects)
          

          打印:

          This Living Room looks clean!
          This Couch looks comfortable...
          This Restrooms looks clean!
          This Bed looks comfortable...
          

          至于您的具体问题:可能您忘记从examine() 返回一个值? (请发布完整的错误消息(包括完整的回溯)。)

          然后我有一个函数字典,我想将对象传递给函数。但是,我遇到了一些问题。例如,我有一个字典:

          my_dict = {'look': CallLook(rooms[i])} # this is no dict of functions
          

          您创建的dict 可能评估为{'look': None}(假设您的examine() 没有返回值。)这可以解释您观察到的错误。 如果你想要一个函数的字典,你需要放入一个可调用的,而不是一个实际的函数调用,例如像这样:

          my_dict = {'look': CallLook} # this is a dict of functions
          

          如果您想将'look' 绑定到特定的room,您可以重新定义CallLook

          def CallLook(current_room)
             return current_room.examine # return the bound examine
          my_dict = {'look': CallLook(room[i])} # this is also a dict of functions
          

          您的代码的另一个问题是您通过将本地字典命名为 dict 来隐藏内置的 dict() 方法。你不应该这样做。这会产生严重的错误。

          【讨论】:

          • 这就是问题所在。检查()不返回值。因此,当我调用 my_dict = {'look': CallLook} 时工作正常,但直到现在我才明白 my_dict = {'look': CallLook(rooms[i])} 不是函数字典。非常感谢您的解释
          猜你喜欢
          • 2020-11-07
          • 2018-07-08
          • 1970-01-01
          • 1970-01-01
          • 2016-11-14
          • 2021-07-11
          • 2014-10-08
          • 2012-04-03
          • 1970-01-01
          相关资源
          最近更新 更多