Python - доступ к классу из списка с помощью ключа - PullRequest
1 голос
/ 05 апреля 2010

Есть ли способ заставить список классов вести себя как набор в 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 ]

2 голосов
/ 05 апреля 2010

Почему бы вам просто не сделать:

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

Зачем пытаться создать раскрученный вручную дикт, который использует ключи, отличные от тех, которые вы передаете?(т.е. "Hello" вместо MyStr ("Hello")).

ex.

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 голосов
/ 05 апреля 2010

Просто напишите класс, который ведет себя немного как отображение:

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 голос
/ 05 апреля 2010

Установите и продиктуйте использование значения, возвращенного методом __hash__ объекта, для поиска объекта, так что это будет делать то, что вы хотите:

>>class a:
... def __init__(self, x):
...  self.var = x
...
... def __hash__(self):
...  return hash(self.var)
1 голос
/ 05 апреля 2010

Как я помню, "set" и "dict" используют также __hash__

From Python 2.x doc :

Ключи словаря почти произвольные значения.Значения, которые не hashable , то есть значения, содержащие списки, словари или другие изменяемые типы (которые сравниваются по значению, а не по идентификатору объекта), не могут использоваться в качестве ключей.

0 голосов
/ 05 апреля 2010

Хочешь что-нибудь подобное

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...