Хотя для функций и глобальных переменных это было бы более или менее просто.что странно, используя «dis» для атрибутов класса, это может быть гораздо более запутанным - поскольку тела классов сначала компилируются в объект кода, который запускается один раз, когда класс определен, и все, кроме «выброшенного», один раз класс
На данный момент у вас есть только класс '__dict__
без намеков на порядок создания или место создания вообще.
Также использование dis
сделаетМожно найти, где переменные приписаны поиском кода операции STORE_NAME
, у вас та же проблема, когда вы не знаете , какой из них был запущен , но это будет не более надежно, чем текстовый поиск шаблонов насам исходный код.
Единственный надежный способ сделать это, если вместо использования обычных переменных вы используете специальные дескрипторы - они могут проверить место, где был сделан вызов для установки их значений, и аннотировать, чтов реестре.
Итак, все, что вам нужно, это чтобы переменные, которые вы хотите отследить, находились внутри специального объекта, который может иметь короткое имя - конечный код будет выглядеть так:
from variable_registry import R
class MyClass:
R.name = "the true name"
def __init__(self):
print(R.name)
Это потребует особой обработки, если вам нужны переменные экземпляра, но все же это может быть сделано более сложным механизмом.Для классовых и глобальных переменных вам будет хорошо, как для локальных переменных при не параллельном выполнении.
import sys
class Registry:
def __init__(self):
self.__dict__["_registry"] = {}
def __setattr__(self, name, value):
frame = sys._getframe().f_back
file = frame.f_globals["__file__"]
self.__dict__["_registry"][name] = file, frame.f_lineno, value
super().__setattr__(name, value)
R = Registry()