Python - 使用密钥从列表中访问类

时间:2010-04-05 08:42:24

标签: python class

有没有办法让类的列表在python中表现得像一个集?

基本上,我正在开发一个涉及字符串比较的软件,我有一个用于处理字符串的自定义类。因此,每个字符串都有一个类的实例。

结果,我有一个包含所有这些类的大型列表。我希望能够像list[key]一样访问它们,在这种情况下,键是一个类所基于的字符串(注意:一旦实例化类,字符串将永远不会改变,所以它应该是哈希的)。

在我看来,我应该能够轻松地做到这一点,通过在课堂上添加类似__cmp__之类的东西,但要么我是愚蠢的(可能),要么我错过了文档。

基本上,我希望能够做这样的事情(Python提示示例):

>>class a:
... def __init__(self, x):
...  self.var = x
...
>>> from test import a
>>> cl = set([a("Hello"), a("World"), a("Pie")])
>>> print cl
set([<test.a instance at 0x00C866C0>, <test.a instance at 0x00C866E8>, <test.a instance at 0x00C86710>])
>>> cl["World"]
<test.a instance at 0x00C866E8>

谢谢!

编辑一些额外的调整:

class a:
... def __init__(self, x):
...     self.var = x
... def __hash__(self):
...     return hash(self.var)
...
>>> v = a("Hello")
>>> x = {}
>>> x[v]=v
>>> x["Hello"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'Hello'
>>> x["Hello"]

5 个答案:

答案 0 :(得分:2)

只需编写一个行为有点像映射的类:

class ClassDict(object):
  def __init__(self):
    self.classes = {}

  def add(self, cls):
    self.classes[cls.__name__] = cls

  def remove(self, cls):
    if self.classes[cls.__name__] == cls:
      del self.classes[cls.__name__]
    else:
      raise KeyError('%r' % cls)

  def __getitem__(self, key):
    return self.classes[key]

  def __repr__(self):
    return 'ClassDict(%s)' % (', '.join(self.classes),)

class C(object):
  pass

class D(object):
  pass

cd = ClassDict()
cd.add(C)
cd.add(D)

print cd

print cd['C']

答案 1 :(得分:2)

你为什么不这样做:

>>> v = MyStr("Hello")
>>> x = {}
>>> x[v.val]=v
>>> x["Hello"]
MyStr("Hello")

为什么要尝试创建一个使用不同于你传入的键的手动dict的麻烦? (即“你好”而不是MyStr(“你好”))。

离。

class MyStr(object):
    def __init__(self, val):
        self.val = str(val)

    def __hash__(self):
        return hash(self.val)

    def __str__(self):
        return self.val

    def __repr__(self):
        return 'MyStr("%s")' % self.val


>>> v = MyStr("Hello")
>>> x = {}
>>> x[str(v)]=v
>>> x["Hello"]
MyStr("Hello")

答案 2 :(得分:1)

我记得“set”和“dict”也使用__hash__

来自Python 2.x doc

  

字典的键是几乎任意值。非hashable的值,即包含列表,字典或其他可变类型的值(通过值而不是按对象标识进行比较)不能用作键。

答案 3 :(得分:1)

Set和dict使用对象的__hash__方法返回的值来查找对象,这样就可以做到你想要的了:

>>class a:
... def __init__(self, x):
...  self.var = x
...
... def __hash__(self):
...  return hash(self.var)

答案 4 :(得分:0)

你想要这样的东西

class A(object):
    ALL_INSTANCES = {}
    def __init__(self, text):
        self.text = text
        self.ALL_INSTANCES[self.text] = self



a1 = A("hello")
a2 = A("world")

print A.ALL_INSTANCES["hello"]

输出:

<__main__.A object at 0x00B7EA50>