为什么对str或int进行子类化的行为与对列表或dict进行子类化的行为不同?

时间:2018-12-10 15:15:06

标签: python class inheritance

从字符串继承时,将打印出传递给argument的值:

class StringChild(str):

    def __init__(self, argument):
        self.argument = argument

print(Child("text"))

输出:

text

从int继承时的情况相同:

class IntChild(int):

    def __init__(self, argument):
        self.argument = argument

print(IntChild(10))

输出:

10

但是,当我从列表或字典继承时,我分别得到一个空列表或字典:

class ListChild(list):

    def __init__(self, argument):
        self.argument = argument

print(ListChild([1,2,3]))

输出:

[]

为什么会有不同的行为?

1 个答案:

答案 0 :(得分:4)

初始化self.argument = argument并不会真正初始化对象本身(列表),而只是设置一个名为argument的任意属性。

如果您使用的是像样的IDE,您应该会看到警告Call to __init__ of super class is missing

如果这样做,您将获得列表:

class ListChild(list):
    def __init__(self, argument):
        super().__init__(argument)
        # self.argument = argument

print(ListChild([1, 2, 3]))
# [1, 2, 3]

您甚至不需要self.argument

现在,在将int子类化时,您也会看到相同的警告。 intlist之间的区别在于int是原始的,工作方式略有不同。您甚至不需要将argument传递到super().__init__。但是,您需要将其传递给IntChild.__init__

class IntChild(int):
    def __init__(self, argument):
        super().__init__()

print(IntChild(3))
# 3

有关int的工作方式的更多详细信息,请参见this question

鼓励用户直接继承collections.UserListcollections.UserString而不是liststr的子类,但是没有UserInt