Отличать собственный тип от пользовательского типа ⇐ Python

Программы на Python
Anonymous
Отличать собственный тип от пользовательского типа

Сообщение Anonymous »

Я хочу иметь возможность отличать какой-либо собственный класс, например _functools.partial (код, код) от некоторого пользовательского класса, например:

Код: Выделить всё

class MyClass:
pass
Я хочу протестировать это изнутри Python (поэтому не использую API CPython или что-то в этом роде). Но ничего страшного, если это работает только с CPython. Это должно работать для CPython >=3.6.
Как?
Более конкретно, я хочу различать объекты, где есть __dict__/

Код: Выделить всё

__slots__
не предоставит мне все атрибуты объекта. Обычно это относится к собственным типам, таким как _functools.partial, где func, args, ключевые слова отсутствуют в __dict__ (и __slots__ не существует).
Я думаю, что в основном я хочу проверить, определяет ли тип некоторые пользовательские Py_tp_members (но не производные от __slots__ (см.)).

Некоторые общие сведения/идеи, которые могут оказаться полезными для ответа:
  • Код: Выделить всё

    functools.partial.__dict__
    обычно пуст или отсутствует.
  • Код: Выделить всё

    functools.partial.__slots__
    существует только в том случае, если Python использует чистую реализацию Python, что обычно не так.
  • Код: Выделить всё

    functools.partial.__getstate__()
    существует начиная с Python >=3.11 и возвращает __dict__ (и, возможно, __slots__), поэтому в случае собственного частичного он будет пустым или None . (Не уверен, что это действительно так. См. проблему CPython № 125094.)
  • Код: Выделить всё

    functools.partial.__dir__(functools.partial)
    также не распространяется на func и co? Однако dir(functools.partial) делает это? Дополнительный вопрос: что встроенный каталог делает по-другому? Где находится точный код встроенного каталога, который охватывает этот случай? Я предполагаю, что он перебирает Py_tp_members, может быть, также Py_tp_methods?
  • Сначала я думал, что, возможно, __dictoffset__ дает мне какую-то подсказку, но это оказалось это неправильно.
  • Встроенный каталог, вероятно, можно использовать в любом случае. Inspect.getmembers (или Inspect.getmembers_static) может рассказать мне то, что мне нужно знать.
Зачем мне это нужно?
Нам необходимо определить наш собственный хеш (не __hash__) для любого типа объекта стабильным способом (который хэш не меняется в разных версиях Python) и значимым образом (что хэш содержит все соответствующие состояния). До сих пор мы перебирали __getstate__() или __dict__/.

Код: Выделить всё

__slots__
, который отлично работает в большинстве случаев, за исключением functools.partial, и, вероятно, для других собственных типов. Идея заключалась в том, чтобы добавить проверку, есть ли у нас собственный тип, и если да, то вернуться к использованию dir, поскольку это работает нормально даже в таких случаях.
См. выпуск Sisyphus № 207, а также Sisyphus get_object_state и Sisyphus sis_hash_helper.

Подробнее здесь: https://stackoverflow.com/questions/790 ... -user-type

Вернуться в «Python»