Можно ли проверить obj .__ dict__, если в классе есть переменная __dict__?

Меня интересует, есть ли способ безошибочно проанализировать экземпляр Python, чтобы увидеть его __ dict __ , несмотря на любые препятствия, которые программист мог бы создать на этом пути, потому что это поможет мне отладить такие проблемы, как непреднамеренные циклы ссылок и зависшие ресурсы, такие как открытые файлы.

Более простой пример: как я могу увидеть ключи подкласса dict , если программист спрятал keys () за собственным классом? Чтобы решить эту проблему, нужно вручную вызвать метод dict keys () вместо того, чтобы позволить наследованию вызывать версию метода подкласса:

# Simple example of getting to the real info
# about an instance

class KeyHidingDict(dict):
    def keys(self):
        return []  # there are no keys here!

khd = KeyHidingDict(a=1, b=2, c=3)
khd.keys()       # drat, returns []
dict.keys(khd)   # aha! returns ['a', 'b', 'c']

Теперь мой актуальный вопрос: как я могу увидеть __ dict __ экземпляра, независимо от того, что мог сделать программист, чтобы скрыть его от меня? Если они устанавливают переменную класса __ dict __ , тогда она, кажется, затеняет фактический __ dict __ любых объектов, унаследованных от этого класса:

# My actual question

class DunderDictHider(object):
    __dict__ = {'fake': 'dict'}

ddh = DunderDictHider()
ddh.a = 1
ddh.b = 2
print ddh.a        # prints out 1
print ddh.__dict__ # drat, prints {'fake': 'dict'}

Это ложное значение для __ dict __ делает как видите, не мешает фактической установке и получению атрибутов, но вводит в заблуждение dir () , скрывая a и b и отображая fake вместо переменной экземпляра объекта.

И снова моя цель - написать инструмент, который поможет мне проанализировать экземпляры класса, чтобы увидеть, «что на самом деле происходит», когда мне интересно, почему набор экземпляров класса занимает так много памяти или держит так много файлов открытыми - и даже несмотря на то, что описанная выше ситуация является чрезвычайно надуманной, поиск пути ее решения позволил бы инструменту работать все время вместо того, чтобы говорить «отлично работает, если только класс, на который вы смотрите, не имеет… [описание исключительной ситуации выше]».

Я думал, что смогу безошибочно захватить __ dict __ примерно так:

dict_descr = object.__dict__['__dict__']
print dict_descr(ddh, DunderDictHider)

Но оказалось, что объект не имеет дескриптора __ dict __ . Вместо этого функция subtype_dict () C, кажется, отдельно присоединяется к каждому подклассу объекта , который создает программист; не существует централизованного способа присвоения имени или получения дескриптора, чтобы его можно было вручную применить к объектам, класс которых его затмевает.

Есть идеи, кто-нибудь? :)

6
задан Brandon Rhodes 22 September 2011 в 08:15
поделиться