Из python можно ли отслеживать назначения на уровне модуля до (другого) кода пользователя?

Я работаю над инструментом, который будет полезен для возможности отслеживать все ссылки на данный объект изнутри python.

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

from a import b 

Если a является модулем, b является ссылкой на объект с именем ab, но это отдельная ссылка. Если моя тестовая двойная система позже заменяет ab, cb все равно будет ссылаться на исходный объект.

Я хотел бы, чтобы мой инструмент отслеживал все назначения ab для псевдонимов, но сглаживание на уровне модулей проделало бы долгий путь к моей цели.

Метафорически, я бы хотел переопределить Module.__setattribute__ :

 def __setattribute__(self, name, value): if isinstance(value, interesting_types): # remember this use of the interesting object and call super for normal processing. 

Предположим, что я могу загрузить свой код, прежде чем модули, которые можно отслеживать, могут быть загружены.

One Solution collect form web for “Из python можно ли отслеживать назначения на уровне модуля до (другого) кода пользователя?”

Это может сработать для вас. Во-первых, некоторый код:

a.py

 b = 42 # other module definitions 

fakery.py

 class Fakery(object): def __init__(self, mod): self.module = __import__(mod) import sys sys.modules[self.module.__name__] = self def __getattr__(self, name): print "__getattr__ called with '%s'" % name result = getattr(self.module, name) if name == 'b': result += 1 return result 

пример

 >>> import fakery >>> fakery.Fakery('a') <fakery.Fakery object at 0x109007110> >>> from a import b __getattr__ called with '__path__' __getattr__ called with 'b' >>> print b 43 >>> import a >>> print a <fakery.Fakery object at 0x109007110> 

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

Я надеюсь, что это ясно, как это работает, но вот краткое объяснение.

Когда модуль импортируется, запись его sys.modules в sys.modules . Когда вы создаете экземпляр объекта Fakery , он выполняет импорт модуля по имени (используя __import__ ), а затем сам заменяет запись этого модуля в sys.modules .

Python только импортирует модули один раз, сохраняя импортированный модуль в sys.modules . Каждый импорт после первого возвращает запись в sys.modules. Объект Fakery вставляет себя в sys.modules['a'] , sys.modules['a'] реальный модуль. Все последующие import a или from a import <whatever> операторов from a import <whatever> теперь направлены на экземпляр Fakery . Поскольку это всего лишь класс, вы можете делать всевозможные сумасшедшие вещи, используя магические методы или метапрограммирование.

__getattr__ удобен, потому что он вызывается, когда запрашиваемый атрибут не существует.

  • Ошибки необъяснимой колбы 404
  • Перенаправление на URL-адрес с данными POST с использованием Python Bottle
  • Могу ли я найти путь исполняемого файла, запускающего скрипт python из сценария python?
  • Потоковые данные с Python и Flask
  • Питоновский способ подключения функции генератора питона для формирования конвейера
  • Стоимость функции len ()
  • значение частоты элементов в python
  • Получить полную трассу
  • Python - лучший язык программирования в мире.