【问题标题】:Why can't *args be passed to super().__init__() from class that overrides int?为什么 *args 不能从覆盖 int 的类传递给 super().__init__()?
【发布时间】:2020-10-10 15:49:01
【问题描述】:
class MyInt(int):
   def __new__(cls, *args, **kwargs):
       print(repr(args), repr(kwargs))
       return super(MyInt, cls).__new__(cls, *args, **kwargs)
   def __init__(self, *args, **kwargs):
       print(repr(args), repr(kwargs))
       return super(MyInt, self).__init__(*args, **kwargs)

MyInt(1)

此代码输出:

(1,) {}
(1,) {}
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-a45744cab1af> in <module>()
----> 1 MyInt(1)

<ipython-input-3-a38fc9aae2fe> in __init__(self, *args, **kwargs)
      5     def __init__(self, *args, **kwargs):
      6         print(repr(args), repr(kwargs))
----> 7         return super(MyInt, self).__init__(*args, **kwargs)
      8 

TypeError: object.__init__() takes no parameters

似乎基础__init__() 期待args,因为我可以打印它们。那么为什么我不能将它们传递给基类的方法呢? (顺便说一句,这在 python 2.7 中运行良好)

【问题讨论】:

  • int 类实例是不可变的,因此它们的值由它们的__new__() 设置,而不是它们的__init__() 方法,它不接受参数——您可以更改或覆盖的东西。跨度>
  • 如果 __init__() 不接受参数,那么为什么我可以打印它们?另请参阅覆盖 int 的内置类 bool 的声明。 gist.github.com/grandquista/…
  • 我的意思是“……你不能改变或覆盖的东西”。
  • 好的,但是为什么int 将参数传递给我的自定义__init__()
  • 是的,我就是这个意思。问题是args 没有被int 识别,只是被向上传递给object.__init__(这会引发错误,而不是简单地忽略意外参数)。这就是为什么错误消息指的是object.__init__,而不是int.__init__

标签: python python-3.x constructor int


【解决方案1】:

由于int 对象是不可变的,所以不能使用__init__ 方法。正如this documentation 中所述,您必须使用__new__

在这里,当您创建新的MyInt 时,它会优先使用__init__ 方法,这就是您收到错误的原因。所以只需去掉__init__ 方法并保留__new__ 一个。

希望我有用。

【讨论】:

  • 对不起,我找不到说我不能使用__init__ 的字眼。您能在文档中指出这一点吗?另外,为什么这对 bool 有效? gist.github.com/grandquista/…
  • @raacer "在许多类中,我们使用__init__ 来改变新构造的对象,通常是通过存储或以其他方式使用__init__ 的参数。但是我们不能用子类来做到这一点int (或任何其他不可变的),因为它们是不可变的。”
  • 你看过bool的实现吗?而且您是否注意到init 将参数传递给我的__init__()
  • 上面提供的文本没有告诉“你不能覆盖 __init__()”。它只是说“你不能改变对象”。
猜你喜欢
  • 1970-01-01
  • 2021-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多