Отражение Python

#python #reflection

#python #отражение

Вопрос:

предположим, у нас много объектов в памяти. У каждого из них есть отдельный идентификатор. Как я могу выполнить итерацию в памяти, чтобы найти конкретный объект, который сравнивается с некоторым идентификатором? Для того, чтобы захватить его и использовать через getattr ?

Комментарии:

1. Вы этого не делаете. Просто держите ссылку рядом. Это уже идентификатор в основной реализации и правильная вещь ™, которую нужно делать в любом случае.

Ответ №1:

Вы должны поддерживать коллекцию этих объектов по мере их создания в атрибуте класса, затем предоставить метод класса для их извлечения.

Что-то вроде:

 class Thing(object):
    all = {}

    def __init__(self, id, also, etc):
        self.id = id
        self.all[id] = self

    @classmethod
    def by_id(cls, id):
        return cls.all[id]
  

Ответ №2:

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

Комментарии:

1. 1 Круто, я этого не знал. Я не уверен, что у меня когда-нибудь будет повод использовать этот лакомый кусочек, но тем не менее классный.

Ответ №3:

Вы можете создать параметр ‘registry’, на который подписываются все новые экземпляры, с помощью сопоставления ID-> objects:

 registry = {}

class MyClass(object):
    def __init__(self, ...):
        id = ...
        registry[id] = self

MyClass.__all__ = registry
  

Это эквивалентно другому принятому решению (другое, однако, более «питоническое»). Ранее я улучшал этот метод двумя способами: 1) вы можете создать пользовательский класс контейнера для реестра, который позволяет вам выполнять поиск не только по идентификаторам; 2) вы также можете создать метакласс, который автоматически добавляет код, но это может стать некрасивым, если вам также нужны метаклассы для чего-то еще.

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

Ответ №4:

Во-первых, всем вам, кто ответил мне, большое спасибо, то, что у меня было в голове во время выходных, было вот что :

 for ech in globals():
        if str(type(globals()[ech])).find('instance') != -1:
            if ( globals()[ech].__dict__.has_key('onoma')):
                print "%s, %s, %s"%( ech, globals()[ech].__dict__, id(globals()[ech]) )
  

который выполнил свою работу, хотя я не знаю, хороший это или плохой подход («онома» — греческое слово, обозначающее название).
Я прочитал в документах Pyton о: _id2obj_dict = weakref .WeakValueDictionary() из weakref . И с этим я тоже попробовал. Хороший подход и, я думаю, похож на Ned и ninjagecko.
Но в этом случае, как я могу быть уверен, что объект полностью освобожден из памяти?