Методы объекта Python dict - PullRequest
       4

Методы объекта Python dict

0 голосов
/ 24 декабря 2011

Мне нужна переменная экземпляра класса, содержащая список обработчиков (указанные методы этого экземпляра класса).Список обработчиков предоставляется по запросу.

У меня есть два решения, но ни одно из них мне не подходит.

  1. http://www.ideone.com/3aSkT - Вы получите циклическийссылка.GC может очистить его, но мы не знаем, когда.
  2. http://www.ideone.com/OaP5c - Здесь, когда вы вызываете, вам нужно явно передать экземпляр класса в функцию.

Есть еще предложения?

Ответы [ 3 ]

2 голосов
/ 24 декабря 2011

Если я правильно понял, вы могли бы просто использовать встроенную функцию dir().Пример:

>>> class Foo(object):
...     def m1(self):
...         pass
...     def m2(self):
...         pass
... 
>>> dir(Foo)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'm1', 'm2']
>>> [m for m in dir(Foo) if '__' not in m]
['m1', 'm2']

РЕДАКТИРОВАТЬ: Ваш вопрос и ваши комментарии не совсем понятны.Было бы полезно, если бы вы могли отредактировать свой вопрос, указав ожидаемый результат.Мое лучшее предположение, читая ваш комментарий здесь ( "Мне нужен этот словарь {int type: method type}" ), вы можете захотеть:

>>> dict(enumerate([getattr(Foo, m) for m in dir(Foo) if '__' not in m]))
{0: <unbound method Foo.m1>, 1: <unbound method Foo.m2>}

EDIT2: Когда вы пишете:

packet_ids_to_check_up = (0x0404, 0x0405, 0x0404, 0x0505, 0x0506)
    for packet_id in packet_ids_to_check_up:
        if packet_id in some_class_obj:
            some_class_obj[packet_id]('Hello world')

, вы, похоже, ожидаете, что ваш класс будет действовать как словарь.В этом случае вам, вероятно, следует взглянуть на модуль collections.abc и, в частности, класс MutableMapping.Из Python Glossary :

mapping - Контейнерный объект, который поддерживает поиск произвольных ключей и реализует методы, указанные в абстрактных базовых классах Mapping или MutableMapping.Примерами могут служить dict, collection.defaultdict, collection.OrderedDict и collection.Counter.

Это подразумевает реализацию следующих методов:

  • __contains__
  • keys
  • items
  • values
  • get
  • __eq__
  • __ne__
  • pop
  • popitem
  • clear
  • update
  • setdefault

Тем не менее, из вашего кода не совсем очевидно, почему вы не можете просто обойтись без использования простого словаря (или, в конечном итоге, подкласса dict напрямую ...).

Помогает ли это?

1 голос
/ 24 декабря 2011

Я не уверен, что понимаю вашу проблему, но если вы хотите "сопоставить" имена методов с другими методами (вызов Foo().store() фактически вызовет Foo().someMethod()) без ссылки на них, вы можете сделать это, переопределивповедение по умолчанию object.__getattribue__.

class Foo(object):
    mapping = {'store': 'someMethod'}

    def __getattribute__(self, attr):
        try:
            # first check if it's a "regular" attribute/method
            return super(Foo, self).__getattribute__(attr)
        except AttributeError:
            # attribute was not found, if it's not in your mapping, re-raise the error
            if attr not in self.mapping:
                raise
            mapped_attr = self.mapping[attr]
            return super(Foo, self).__getattribute__(mapped_attr)

    def someMethod(self):
        print "Foo().someMethod()"

foo = Foo()
foo.store()

Выход:

>>> Foo().someMethod()
1 голос
/ 24 декабря 2011

Расширение ответа @mac с учетом того, что OP запросил переменную экземпляра класса и что он также может захотеть получить информацию о "приватных" методах:

In [5]: class Foo(object):
   ...:     def m1(self):pass
   ...:     def m2(self):pass
   ...:
In [6]: f = Foo()
In [7]: lst = dir(f)
In [8]: [m for m in lst if not m.endswith('__')]
Out[8]: ['m1', 'm2']

Если вам нужен объектный метод:

In [17]: getattr(Foo, 'm1')
Out[17]: <unbound method Foo.m1>

или непосредственно в понимании списка из экземпляра:

In [18]: [getattr(f, m) for m in lst if not m.endswith('__')]
Out[18]:
[<bound method Foo.m1 of <__main__.Foo object at 0x00000000073DD1D0>>,
 <bound method Foo.m2 of <__main__.Foo object at 0x00000000073DD1D0>>]

Редактировать: Итак, учитывая примеры, которые вы приводите в своей ссылке, возможно, вы ищете что-то вроде:

class SomeClass:

    store = {0: 'someMethod', 1: 'someMethod1'}

    def __init__(self):
        print('__init__')

    def __del__(self):
        print('__del__')

    def get_dict(self):
        return [getattr(self, att) for idx, att in SomeClass.store.items()]

    def someMethod(): pass
    def someMethod1(): pass


f = SomeClass()
print f.get_dict()

Что печатает:

__init__
[<bound method SomeClass.someMethod of <__main__.SomeClass instance at 0x0000000
0026E2E08>>, <bound method SomeClass.someMethod1 of <__main__.SomeClass instance
 at 0x00000000026E2E08>>]
__del__
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...