Python: extending int and MRO for __init__

☆樱花仙子☆ 提交于 2019-12-23 07:26:11

问题


In Python, I'm trying to extend the builtin 'int' type. In doing so I want to pass in some keywoard arguments to the constructor, so I do this:

class C(int):
     def __init__(self, val, **kwargs):
         super(C, self).__init__(val)
         # Do something with kwargs here...

However while calling C(3) works fine, C(3, a=4) gives:

'a' is an invalid keyword argument for this function` 

and C.__mro__ returns the expected:

(<class '__main__.C'>, <type 'int'>, <type 'object'>)

But it seems that Python is trying to call int.__init__ first... Anyone know why? Is this a bug in the interpreter?


回答1:


The docs for the Python data model advise using __new__:

object.new(cls[, ...])

new() is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation. It is also commonly overridden in custom metaclasses in order to customize class creation.

Something like this should do it for the example you gave:

class C(int):

    def __new__(cls, val, **kwargs):
        inst = super(C, cls).__new__(cls, val)
        inst.a = kwargs.get('a', 0)
        return inst



回答2:


You should be overriding "__new__", not "__init__" as ints are immutable.




回答3:


What everyone else (so far) said. Int are immutable, so you have to use new.

Also see (the accepted answers to):

  • increment int object
  • Why can't I subclass datetime.date?


来源:https://stackoverflow.com/questions/1184337/python-extending-int-and-mro-for-init

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!