You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python2出现unbound method __init__()错误,Python3正常的原因与解决

Python2与Python3中跨类调用构造函数的差异与兼容方案

问题现象

以下代码在Python3中运行正常,但在Python2.7中会抛出类型错误:

class Base:
  def __init__(self):
    print("base constructor")

class derived(Base):
  def __init__(self):
    print("derived constructor")

class Secondary(Base):
  def __init__(self):
    derived.__init__(self)

s = Secondary()

Python2.7执行报错:

$ python2.7 test.py
Traceback (most recent call last):
  File "test.py", line 13, in <module>
    s = Secondary()
  File "test.py", line 11, in __init__
    derived.__init__(self)
TypeError: unbound method __init__() must be called with derived instance as first argument (got Secondary instance instead)

尝试改用super(已让Base继承object)后,Python2.7仍报错:

class Base(object):
  def __init__(self):
    print("base constructor")

class derived(Base):
  def __init__(self):
    print("derived constructor")

class Secondary(Base):
  def __init__(self):
    super(derived, self).__init__()

s = Secondary()

报错信息:

$ python2.7 test.py
Traceback (most recent call last):
  File "test.py", line 13, in <module>
    s = Secondary()
  File "test.py", line 11, in __init__
    super(derived, self).__init__()
TypeError: super(type, obj): obj must be an instance or subtype of type

原因分析

  1. Python2与Python3的方法绑定机制差异

    • Python2中,类的方法默认是未绑定方法,调用时会严格检查第一个参数的实例类型是否属于该类或其子类。derived.__init__作为未绑定方法,要求传入的self必须是derived的实例,而Secondary实例不符合要求,因此报错。
    • Python3中,类的方法被视为普通函数,不再做强制的类型检查,只要传入的参数符合方法定义即可执行,因此derived.__init__(self)能正常运行。
  2. super的用法错误
    使用super(derived, self)时,super要求第二个参数self必须是第一个参数derived的实例或子类实例,但self是Secondary的实例,和derived没有继承关系,因此触发类型错误。

兼容Python2的解决方案

方案1:调用方法的底层函数跳过类型检查

在Python2中,可以通过__func__属性直接获取方法对应的底层函数,绕开未绑定方法的类型检查:

class Base:
  def __init__(self):
    print("base constructor")

class derived(Base):
  def __init__(self):
    print("derived constructor")

class Secondary(Base):
  def __init__(self):
    derived.__init__.__func__(self)

s = Secondary()

方案2:调整继承关系后正确使用super

如果业务允许Secondary继承自derived而非Base,可以正常使用super实现逻辑复用:

class Base(object):
  def __init__(self):
    print("base constructor")

class derived(Base):
  def __init__(self):
    print("derived constructor")
    super(derived, self).__init__()

class Secondary(derived):
  def __init__(self):
    super(Secondary, self).__init__()

s = Secondary()

方案3:直接复用构造逻辑(不推荐)

如果只是想复用derived的构造逻辑,也可以提取独立函数供两个类调用,避免跨类调用构造函数的问题:

class Base:
  def __init__(self):
    print("base constructor")

def derived_init_logic():
    print("derived constructor")

class derived(Base):
  def __init__(self):
    derived_init_logic()

class Secondary(Base):
  def __init__(self):
    derived_init_logic()

s = Secondary()

内容的提问来源于stack exchange,提问作者roulette01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 19:37:39