Извините, это невозможно без создания собственного пользовательского переводчика. Литеральные объекты не создаются путем вызова конструктора в __builtins__
, они создаются с использованием кодов операций, которые напрямую вызывают встроенные типы.
Кроме того, неизменные литералы создаются при компиляции кода, так что вы все равно опоздали. Если вы дизассемблируете testMethod
, вы увидите, что он просто использует скомпилированные константы, но не пытается их построить:
>>> dis.dis(TestClass.testMethod)
5 0 LOAD_CONST 1 (1)
2 STORE_FAST 1 (a)
6 4 LOAD_CONST 2 (2)
6 STORE_FAST 2 (b)
7 8 LOAD_FAST 1 (a)
10 LOAD_FAST 2 (b)
12 BINARY_ADD
14 STORE_FAST 3 (c)
16 LOAD_CONST 0 (None)
18 RETURN_VALUE
Изменяемые литералы создаются во время выполнения, но они используют коды операций для создания подходящего значения вместо вызова типа:
>>> dis.dis(lambda: {'a': 1, 'b': 2})
1 0 LOAD_CONST 1 (1)
2 LOAD_CONST 2 (2)
4 LOAD_CONST 3 (('a', 'b'))
6 BUILD_CONST_KEY_MAP 2
8 RETURN_VALUE
Вы можете сделать что-то в соответствии с тем, что вы хотите, проанализировав исходный код (используйте встроенный compile()
с флагом ast.PyCF_ONLY_AST
), затем пройдясь по дереву разбора и заменив литералы int
на позвоните на ваш собственный тип (используйте ast.NodeTransformer
). Затем все, что вам нужно сделать, это закончить компиляцию (используйте compile()
снова). Вы могли бы даже сделать это с помощью ловушки импорта, чтобы это происходило автоматически при импорте вашего модуля, но это будет грязно.