【问题标题】:Can class instances be accessed via an index in python?可以通过python中的索引访问类实例吗?
【发布时间】:2018-05-07 20:16:48
【问题描述】:

例如,假设我们有一个“代理”类,如下所示:

class Agent:

    def __init__(self, number):
        self.position = [] 
        self.number = number         
        for i in range(number):
             self.position.append([0, 0])

我可以通过以下方式创建类的实例:

agent = Agent(10)

然后通过以下方式访问第 i 个代理的位置:

agent.position[i]

但是,这似乎不够优雅,对我来说有点违反直觉。相反,我想索引类实例本身。例如:

pos_i = agent[i].position

它应该返回与上面的单行代码相同的答案。有没有办法做到这一点?

【问题讨论】:

  • 但是position 是职位历史列表?
  • 此外,您所说的不正确。您不访问第 i 个代理的位置,而是访问代理的第 i 个位置。
  • 那么是否可以创建代理的 i 个实例,或者这是否是多余的?重点是能够通过某些功能改变这些位置。 @WillemVanOnsem
  • 但是在这里您将职位列表附加到一个代理。
  • 嗯,我的目标是能够更改具有相同属性的类实例的位置。所以我的初始代码足以完成这项任务,对吧? @WillemVanOnsem

标签: python oop indexing


【解决方案1】:

如果你想这样做,你只需要一个包含所有实例的类级容器。

由于您的职位(以您的示例为例)是按任意顺序创建的,因此我建议您使用字典。

您可以只填写班级级别的“职位”字典。然后,您可以只实现 __getitem__ 方法来从该字典中检索元素:

class Agent:
   position = {}
   def __new__(cls, pos):
       if pos in cls.position:
           return cls.position[pos]
       instance = super().__new__(cls)
       cls.position[pos] = instance
       return instance

   def __getitem__(self, item):
        return self.position[pos]

然而,这将只允许您从实例中检索给定位置的实例 - 即:

agent_5 = Agent(5)
agent_10 = agent_5[10] 

可以,但不行:

agent_10 = Agent[10] 

如果你想这样,你必须使用自定义元类,并将__getitem__ 方法放在那里:

class MAgent(type):
   def __getitem__(cls, item):
        return cls.position[pos]


class Agent(metaclass=MAgent):
   position = {}
   def __new__(cls, pos):
       if pos in cls.position:
           return cls.position[pos]
       instance = super().__new__(cls)
       cls.position[pos] = instance
       return instance

【讨论】:

    【解决方案2】:

    如果你想重载索引操作符,只需重载类中的__getitem__ 方法。

    class Agent:
        def __getitem__(self, key):
            return self.position[key]
    
    >>> myobj = MyClass()
    >>> myobj[3]
    

    【讨论】:

      猜你喜欢
      • 2021-07-18
      • 1970-01-01
      • 1970-01-01
      • 2018-09-03
      • 2018-01-05
      • 1970-01-01
      • 2011-10-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多