【问题标题】:Subclassing builtin types -- Python 2 and 3子类化内置类型——Python 2 和 3
【发布时间】:2014-02-26 10:29:32
【问题描述】:

我的代码如下所示:

class Token(object):
    '''
    Resulting from parse
    '''
    def __new__(cls,text,begin,end,*args,**kargs):
        self = super(Token,cls).__new__(cls,*args,**kargs)
        return self

    def __init__(self,text,begin,end,*args,**kargs):
        super(Token,self).__init__(*args,**kargs)
        self.text = text
        self.begin = begin
        self.end = end

class List(Token,list):
    pass

class Str(Token,str):
    pass

class Int(Token,int):
    pass

s = Str('hey there',0,3,'hey there'[0:3])
print(s)

x = Int('55 12',0,2,'55 12'[0:2])
print(x)

基本上,我想做的是轻松创建只是普通 Python 类型的类型,但需要为它们提供一些额外信息。

Python 2 似乎对上面的代码没问题,但是 Python 3 抱怨

Traceback (most recent call last):
  File "simple.py", line 71, in <module>
    s = Str('',1,2,'hey')
  File "simple.py", line 12, in __init__
    super(Token,self).__init__(*args,**kargs)
TypeError: object.__init__() takes no parameters

如果我这样做,我认为口译员会很高兴

class List(list):
    def __init__(self,text,begin,end,*args,**kargs):
        list.__init__(*args,**kargs)

但这意味着我必须为我想要制作的每个新课程重复类似的内容......而且我宁愿保持相对干燥......

是否有一种“正确”的方式来处理这种情况,以便 Python 2 和 Python 3 都满意?

【问题讨论】:

    标签: python python-2.7 python-3.x


    【解决方案1】:

    最好的办法是在这里使用异常处理:

    def __init__(self,text,begin,end,*args,**kargs):
        try:
            super(Token,self).__init__(*args,**kargs)
        except TypeError:
            # Python 3 and the mixed in type is immutable.
            # Ignoring this is fine, `__new__` took care of this.
            pass
        self.text = text
        self.begin = begin
        self.end = end
    

    【讨论】:

    • 谢谢,效果很好!但是,我有点困惑......即使混合类型是不可变的,虚拟 __init__ 不应该考虑额外的参数吗?为什么会出现 TypeError?
    • @math4tots:可变类型有一个__init__ 方法,不可变类型没有。所以list.__init__ 存在,unicode.__init__ 不存在。这意味着对于不可变类型,object.__init__ 被调用。 object.__init__ 接受的规则在 Python 2 和 3 之间发生了变化。
    • 非常感谢!你提到的那个链接真的为我澄清了我对__new____init__的一些基本误解
    • @math4tots:很高兴今天能帮到你两次! :-)
    猜你喜欢
    • 1970-01-01
    • 2019-12-27
    • 2021-07-08
    • 2017-06-07
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多