#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.
Но в этом случае, как я могу быть уверен, что объект полностью освобожден из памяти?