在Python中对int类进行子类化

时间:2018-11-05 15:44:02

标签: python-3.x built-in subclassing

每次我在TestClass中添加两个整数时,我都想做些事情。

import builtins

class myInt(int):
    def __add__(self, other):
        print("Do something")

class TestClass:
    def __init__(self):
        builtins.int = myInt

    def testMethod(self):
        a = 1
        b = 2
        c = a + b

当我打电话给testMethod时,什么也没发生,但是如果我这样定义,我会得到预期的效果:

    def testMethod(self):
        a = int(1)
        b = 2
        c = a + b

是否有可能使所有int文字都可以使用而不必在操作之前进行类型转换?

1 个答案:

答案 0 :(得分:2)

对不起,没有构建自己的自定义解释器是不可能的。文字对象不是通过在__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标志)来执行所需的操作,然后遍历解析树并替换{ {1}}个文字,可以调用您自己的类型(使用int)。然后,您要做的就是完成编译(再次使用ast.NodeTransformer)。您甚至可以使用导入挂钩来执行此操作,这样在导入模块时它会自动发生,但是会很麻烦。