英文:
unbound method __init__() error with python2 but not with python3
问题
这与我之前的问题有关:https://stackoverflow.com/questions/76324839/unbound-method-init-error-in-unit-tests-but-not-in-regular-executions?noredirect=1#comment134593579_76324839
我创建了一个下面的最小可重现示例:
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()
如果你使用 python3.7
(或任何 Python3 版本,我认为都可以),它可以正常运行,但是在 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)
为什么这在 Python3 中可以正常工作,但在 Python2 中不行?是否有办法让这在 Python2 中工作?
我也尝试使用 super
(必须让 Base
继承 object
才能使用它):
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 中仍然存在问题。错误消息变了(我认为意思类似):
$ 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
英文:
This is related to my earlier question: https://stackoverflow.com/questions/76324839/unbound-method-init-error-in-unit-tests-but-not-in-regular-executions?noredirect=1#comment134593579_76324839
I made a minimal reproducible example below:
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()
If you run this with python3.7
(or any python3 version I think), it works fine, but with python2.7
, you get the error
$ 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)
Why does this work with python3 but not python2? Is there a way to make this work with python2?
Also tried using super
(had to make Base
inherit object
to use it):
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()
There's still an issue with python2
. The error changes (similar meaning I think):
$ 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
得分: 2
在Python 2中,访问一个function
类型的类属性始终会产生一个instancemethod
实例,无论您是通过类还是类的实例来访问它。
>>> class Foo(object):
... def __init__(self):
... pass
...
>>> type(Foo.__init__)
<type 'instancemethod'>
>>> type(Foo().__init__)
<type 'instancemethod'>
唯一的区别在于当您调用instancemethod
时,它是否具有可以传递给函数的对象引用。
>>> f = Foo()
>>> Foo.__init__() # 错误
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method __init__() must be called with Foo instance as first argument (got nothing instead)
>>> Foo.__init__(f) # 正确
>>> f.__init__() # 正确
在Python 3中,访问类上的function
类型的类属性会产生原始函数;只有当您通过类的实例访问它时,才会得到一个method
实例。
>>> class Foo:
... def __init__(self):
... pass
...
>>> type(Foo.__init__)
<class 'function'>
>>> type(Foo().__init__)
<class 'method'>
英文:
In Python 2, accessing a function
-valued class attribute always produces an instance of instancemethod
, whether you access it via the class or an instance of the class.
>>> class Foo(object):
... def __init__(self):
... pass
...
>>> type(Foo.__init__)
<type 'instancemethod'>
>>> type(Foo().__init__)
<type 'instancemethod'>
The only difference is whether the instancemethod
has a reference to an object that can be passed to the function when you call the instancemethod
.
>>> f = Foo()
>>> Foo.__init__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method __init__() must be called with Foo instance as first argument (got nothing instead)
>>> Foo.__init__(f) # OK
>>> f.__init__() # OK
In Python 3, accessing a function
-valued class attribute on a class produces the raw function; only when you access it via an instance of the class do you get an instance of method
.
>>> class Foo:
... def __init__(self):
... pass
...
>>> type(Foo.__init__)
<class 'function'>
>>> type(Foo().__init__)
<class 'method'>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论