Пакет для отображения и изменения внутренних структур Python.
Хотите увидеть, как объекты Python устроены внутри?
Тогда этот пакет для вас.
from pystrector import Binder
binder = Binder()
some_object = 1
reflector = binder.bind(some_object)
print(reflector.ob_base.ob_refcnt.pretty_value)Чтобы установить pystrector введите команду.
python3 -m pip install pystrectorgit clone https://github.com/bontail/pystrector.gitЧтобы получить доступ к представлению основных структур, вам необходимо создать объект привязки
from pystrector import Binder
binder = Binder()Теперь вы можете вызвать метод привязки, чтобы получить объект класса, представляющий структуру.
some_object = 1
reflector = binder.bind(some_object)Объект отображателя имеет все те же поля, что и внутренняя структура
// core structure
struct _longobject {
PyObject ob_base;
_PyLongValue long_value;
};class _longobject(DataType, is_union=False):
ob_base = _object()
long_value = _PyLongValue()Если объект содержит anonymous_var, то можно сразу переходить к полям этого объекта
class anonymous_1(DataType, is_union=True):
ob_refcnt = LongLong()
ob_refcnt_split = UnsignedInt[2]
class _object(DataType, is_union=False):
anonymous_var_1 = anonymous_1()
ob_type = Pointer(datatype="_typeobject")
some_object = 1
reflector = binder.bind(some_object).cast_to(_object)
# print(reflector.anonymous_var_1.ob_refcnt.pretty_value)
print(reflector.ob_refcnt.pretty_value)Для каждого типа вы можете вызвать pretty_value и bytes_value
pretty_value - приведет к наиболее похожему типу в Python
bytes_value - всегда возвращает bytearray
print(reflector.long_value.lv_tag.pretty_value)
print(reflector.long_value.lv_tag.bytes_value)Вы также можете устанавливать значения
bytes_value - принимает только bytearray
pretty_value - принимает аналогичный тип Python
без параметров - берет другой объект отображателя
reflector.ob_base.ob_refcnt.bytes_value = bytearray(1)
reflector.ob_base.ob_refcnt.pretty_value = 1000
reflector.ob_base.ob_refcnt = binder.bind(7).ob_base.ob_refcntТакже есть работа с указателями и массивами как в Cи
x = [1, 2, 3]
print(binder.bind(x).ob_item[j][1])
print(+(binder.bind(x).ob_item[j]))
print(+(binder.bind(x).ob_item[j] + 1))Вы можете преобразовать отображатели одних типов данных в другие
from pystrector.core_datatypes import _longobject
x = [1, 2, 3]
binder.bind(x).ob_item[0][0].cast_to(_longobject) # need to cast because list saves PyObjectsИли использовать auto каст (работает только с PyObject)
x = [1, 2, 3]
binder.bind(x).ob_item[0][0].cast()Больше примеров можно увидеть в тестах