【问题标题】:Inheriting from immutable types [duplicate]从不可变类型继承[重复]
【发布时间】:2013-02-11 17:09:45
【问题描述】:

我想知道intliststring 和其他不可变类型的继承是如何工作的。

基本上我只是继承一个这样的类:

class MyInt(int):
    def __init__(self, value):
        ?!?!?

我似乎无法弄清楚,我该如何设置为int 设置的值?如果我这样做self.value = value,那么我的课程将像这样使用:

mi = MyInt(5)
print(mi.value) # prints 5

而我想这样使用它:

mi = MyInt(5)
print(mi) # prints 5

我该怎么做?

【问题讨论】:

    标签: python string list inheritance int


    【解决方案1】:

    你可以继承int,但是因为它是不可变的你需要提供一个.__new__() constructor hook

    class MyInt(int):
        def __new__(cls, value):
            new_myint = super(MyInt, cls).__new__(cls, value)
            return new_myint
    

    您确实需要调用基本的__new__ 构造函数来正确创建您的子类。

    在 Python 3 中,您可以完全省略 super() 的参数:

    class MyInt(int):
        def __new__(cls, value):
            new_myint = super().__new__(cls, value)
            return new_myint
    

    当然,这假设您想在传递给super().__new__() 之前操作value 或在返回之前再操作new_myint;否则你也可以删除整个 __new__ 方法并将其实现为 class MyInt(int): pass

    【讨论】:

    • 好吧,这比我想象的要复杂。但我确实明白它的作用。对于python 3,我不能只使用super()而不是super(MyInt, cls)吗?我还可以为此创建方法和/或其他属性吗?
    • 内部__new__ 调用应该是__new__(cls, value)
    • 哦,顺便说一句,我认为这是值得注意的,如果你真的想在构造上做一些特别的事情(比如初始化其他属性等)。但如果你不这样做,你可以把它排除在外,它会起作用的。所以class MyInt(int): pass 将是一个完美的子类型。
    • @monkut 据我了解,当您调用__new__ 时,该对象尚未构造,因此不存在self 之类的东西(该对象不存在)。 cls 表示类本身,因此我们正在构造该类的新实例。
    • @monkut 这只是一个约定,以明确它不是一个实例方法。传入的值实际上是类型,即对MyInt 的引用,而self 将表示所述类型的实际对象。该对象仅在 __new__ 期间创建。
    猜你喜欢
    • 1970-01-01
    • 2011-08-17
    • 1970-01-01
    • 2012-06-17
    • 2011-08-19
    • 2019-09-02
    • 2016-10-14
    • 1970-01-01
    • 2020-05-01
    相关资源
    最近更新 更多