我试图使用增强而不是重写基类的子类。我正在使用super
方法来调用基类。我发现我需要使用__init__
中的名称修改功能(但仅在init中)才能使代码正常工作。因此,我做了这个打印的例子。因为我没有使用名字改编我期望它来调用子类两次,当我做初始化,而是调用基类在__init__中的python名称mangling似乎不一致
似乎__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'
代码:
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中的self.print
调用子类打印?我期待那个打印基地。当我在init之外调用它时,它会调用基本打印。
我打电话给两个打印看看会发生什么。我正在研究调用超类版本来理解流程。我认为你打我的问题,虽然。基类有一个arg,而子类有两个。当我试图通过超级调用基类时,该方法有2个参数,并且没有匹配。我将不得不考虑那一刻。仍然有点困惑,为什么名字mangling使它的工作。 – kdubs
@kdubs:这个名字让它变得可行,因为在名称改变的情况下,这个方法的每个版本本质上是分开的,并且不能被子类覆盖。所以每个类都会一直在调用它自己的实现。但这通常不是你想要的,因为子类不能覆盖基类实现。基本的问题是你不能采用一个需要一个参数的方法,并用一个需要两个参数的方法来覆盖它;任何用一个调用它的代码现在都会失败。 (在很多情况下,这可以通过为第二个参数给出默认值来处理。) – BrenBarn
请参阅我的更新。打印在init函数中的调用不会按照我期望的方式工作 – kdubs