当前位置:  开发笔记 > 编程语言 > 正文

"TypeError:object()不带参数"将python2元类转换为python3

如何解决《"TypeError:object()不带参数"将python2元类转换为python3》经验,为你挑选了1个好方法。

我正在将一些代码从python2转换为python3,并且我遇到了一个带有元类的错误.

这是工作的python2代码(简化):

#!/usr/bin/env python2
# test2.py

class Meta(type):
    def __new__(mcs, name, bases, clsdict):
        new_class = type.__new__(mcs, name, bases, clsdict)
        return new_class

class Root(object):
    __metaclass__ = Meta

    def __init__(self, value=None):
        self.value = value
        super(Root, self).__init__()

class Sub(Root):
    def __init__(self, value=None):
        super(Sub, self).__init__(value=value)

    def __new__(cls, value=None):
        super(Sub, cls).__new__(cls, value)

if __name__ == '__main__':
    sub = Sub(1)

这是转换后的python3代码:

#!/usr/bin/env python3
# test3.py

class Meta(type):
    def __new__(mcs, name, bases, clsdict):
        new_class = type.__new__(mcs, name, bases, clsdict)
        return new_class

class Root(object, metaclass=Meta):
    def __init__(self, value=None):
        self.value = value
        super(Root, self).__init__()

class Sub(Root):
    def __init__(self, value=None):
        super(Sub, self).__init__(value=value)

    def __new__(cls, value=None):
        super(Sub, cls).__new__(cls, value)

if __name__ == '__main__':
    sub = Sub(1)

如果我跑python2 test2.py,它会运行.如果我这样做python3 test3.py,我会

Traceback (most recent call last):
  File "test.py", line 21, in 
    sub = Sub(1)
  File "test.py", line 18, in __new__
    super(Sub, cls).__new__(cls, value)
TypeError: object() takes no parameters

这不是链接问题的重复,因为在那个问题中,提问者没有正确地调用一个简单的类.在这一个我有代码在python 2中工作,并不适用于2to3运行它



1> Blckknght..:

如在深度通过评论在Python 2的源代码描述的(如由user2357112在评论的链接),Python的认为有一个错误,如果你将参数传递给任一object.__new__object.__init__当两个__init____new__已被覆盖.如果你只覆盖其中一个函数,另一个会忽略多余的参数,但如果你重写它们,你应该确保只传递适当的参数.

在这种情况下,您的Root类会覆盖__init__但不会覆盖__new__,因此object.__new__ 忽略在创建实例时传递给继承的额外参数.

但是,Sub你要覆盖这两种功能,并Sub.__new__传递参数valueobject.__new__super的呼叫.这是您获得例外的地方.

从技术上讲,它在Python 2和Python 3中都是一个错误,但Python开发人员认为在这种情况下引发异常会导致过多的旧代码中断,因此Python 2只发出警告(默认情况下会被禁止).Python 3以其他几种方式破坏了向后兼容性,因此破坏这个问题的旧代码并不是什么大不了的事.

无论如何,修复代码的正确方法是添加一个__new__方法来Root接受和抑制value参数(例如它不会将其传递给object.__new__),或者更改Sub以便它不会将值传递给它的父级所有(例如它只是打电话super(Sub, cls).__new__(cls)).您可能想要考虑一下您是否确实需要两者__new____init__方法Sub,因为大多数类只需要覆盖其中一个.

推荐阅读
k78283381
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有