__init__中的python名称错误似乎不一致

时间:2017-02-26 20:51:40

标签: python

我试图使用增强的子类而不是覆盖基类。我使用Cluster cluster = Cluster.builder().addContactPoint("127.0.0.1").build(); Collection<TableMetadata> tables = cluster.getMetadata() .getKeyspace("keyspace_name") .getTables(); // TableMetadata has name in getName(), along with lots of other info // to convert to list of the names List<String> tableNames = tables.stream() .map(tm -> tm.getName()) .collect(Collectors.toList()); 方法调用基类。我发现我需要在super中使用名称修改功能(但仅限于init?)才能使代码正常工作。所以对于它,我做了这个打印示例。由于我没有使用名称修改,我希望它在执行init时调用子类两次,而是调用基类

似乎__init__有时会看到基类,有时会看到子类。我确定它对我来说只是一个不完整的理解,但我是否需要为真实代码修改名称,在print示例中它调用基类和子类就好了?

代码

__init__

输出 - 为什么不class base: def __init__(self): self.print() def print(self): print("base") class subclass(base): def __init__(self): super(subclass, self).__init__() self.print() def print(self): super(subclass, self).print() print("subclass") x = base() x.print() print("--") y = subclass() y.print() 打印y = subclass()而不是subclass,因为我没有使用名称修改?

base
当我不使用名称修改时,

代码损坏,在我使用> ./y.py base base -- base subclass base subclass base subclass self.__set(注释代码)时有效。当我不使用__set = set时,会出现以下错误:

__set

代码:

File "./x.py", line 5, in __init__
   self.set(arg)
TypeError: set() missing 1 required positional argument: 'arg2'

======= update =======

我重写了代码看起来像这样:

class base:
    def __init__(self, arg):
        self.set(arg)
        # self.__set(arg)

    # __set = set

    def set(self, arg):
        self.arg = arg

    def print(self):
        print("base",self.arg)

class subclass(base):
    def __init__(self, arg1, arg2):
        super(subclass, self).__init__(arg1)
        self.set(arg1, arg2)

    def set(self, arg1, arg2):
        super(subclass, self).set(arg1)
        self.arg2 = arg2

    def print(self):
        super(subclass, self).print()
        print("subclass", self.arg2, self.arg)

x = base(1)

x.print()
x.set(11)
x.print()

y = subclass(2,3)

y.print()
y.set(4,5)
y.print()

当我跑步时,我得到了这个输出:

class base:
    def __init__(self):
        print("base init")
        self.print()

    def print(self):
        print("base print")

class subclass(base):
    def __init__(self):
        print("sc init")
        super(subclass, self).__init__()
        print("sc after super")
        self.print()

    def print(self):
        print("subclass print start")
        super(subclass, self).print()
        print("subclass print")

y = subclass()
print("--")
y.print()

为什么在我启动子类时,基本初始化中的sc init base init subclass print start <<<< why is the subclass print called here base print subclass print sc after super subclass print start base print subclass print -- subclass print start base print subclass print 会调用子类打印?我原以为要打基础打印。当我在init之外调用它时,它会调用基本打印。

1 个答案:

答案 0 :(得分:2)

您的子类print显式调用超类1。因此,每次调用subclass.print时,都将打印“base”和“subclass”。这种情况发生了三次,因为您调用print方法三次:subclass.__init__base.__init__(由subclass.__init__调用)和subclass.print (调用超类版本)。

在“设置”示例中,subclass.__init__调用base.__init__,尝试仅使用一个参数调用self.set。但是,由于您要实例化subclassself.setsubclass.set,这需要两个参数。

目前还不清楚这些例子你想要实现的目标。您的子类实际上不需要调用base.__init__,因为所有这一切都会调用base.set,而您已经从subclass.set调用了它。因此,即使您成功完成了所有调用,也会导致某些方法被多次调用,就像使用print示例一样。

我的印象是,你得到了一点点,试图让每个方法都调用它的超类版本。这并不总是一个好主意。如果你编写一个子类,并且它调用了一个超类方法,你需要确保子类仍然提供一个与超类所期望的兼容的接口。如果没有,您可能需要调用超类方法,而是让子类将其功能“内联”(尽管如果世界上其他类已做出假设,这可能会更具风险)关于基类如何工作)。结果是你总是需要考虑哪些方法称之为其他人;你不能只是在任何地方调用每个超类方法,并期望它能够工作。