我正在努力了解它的用法super().从它的外观来看,可以创建两个子类,就好了.
我很想知道以下2个孩子班级之间的实际差异.
class Base(object):
def __init__(self):
print "Base created"
class ChildA(Base):
def __init__(self):
Base.__init__(self)
class ChildB(Base):
def __init__(self):
super(ChildB, self).__init__()
ChildA()
ChildB()
Run Code Online (Sandbox Code Playgroud) 假设我有一个多继承场景:
class A(object):
# code for A here
class B(object):
# code for B here
class C(A, B):
def __init__(self):
# What's the right code to write here to ensure
# A.__init__ and B.__init__ get called?
Run Code Online (Sandbox Code Playgroud)
有写作两种典型的方法C的__init__:
ParentClass.__init__(self)super(DerivedClass, self).__init__()但是,在任何一种情况下,如果父类(A和B)不遵循相同的约定,则代码将无法正常工作(某些可能会被遗漏,或被多次调用).
那么又是什么样的正确方法呢?很容易说"只是保持一致,遵循一个或另一个",但如果A或B来自第三方图书馆,那么呢?有没有一种方法可以确保所有父类构造函数被调用(并且以正确的顺序,只有一次)?
编辑:看看我的意思,如果我这样做:
class A(object):
def __init__(self):
print("Entering A")
super(A, self).__init__()
print("Leaving A")
class B(object):
def __init__(self):
print("Entering B")
super(B, self).__init__()
print("Leaving B")
class …Run Code Online (Sandbox Code Playgroud) 在Python in a Nutshell(第2版)一书中,有一个示例使用
旧样式类来演示如何以经典分辨率顺序解析方法,
以及它与新顺序的不同之处.
我通过重写新样式的示例尝试了相同的示例,但结果与使用旧样式类获得的结果没有什么不同.我用来运行该示例的python版本是2.5.2.以下是示例:
class Base1(object):
def amethod(self): print "Base1"
class Base2(Base1):
pass
class Base3(object):
def amethod(self): print "Base3"
class Derived(Base2,Base3):
pass
instance = Derived()
instance.amethod()
print Derived.__mro__
Run Code Online (Sandbox Code Playgroud)
调用instance.amethod()打印Base1,但根据我对MRO的理解,新类型的输出应该是Base3.通话Derived.__mro__打印:
(<class '__main__.Derived'>, <class '__main__.Base2'>, <class '__main__.Base1'>, <class '__main__.Base3'>, <type 'object'>)
我不确定我对新样式类的MRO的理解是不正确的还是我做了一个我无法察觉的愚蠢错误.请帮助我更好地了解MRO.
考虑下面的python代码片段
class A(object):
def __init__(self, a):
self.a = a
class B(A):
def __init__(self, a, b):
super(B, self).__init__(a)
self.b = b
class C(A):
def __init__(self, a, c):
super(C, self).__init__(a)
self.c = c
class D(B, C):
def __init__(self, a, b, c, d):
#super(D,self).__init__(a, b, c) ???
self.d = d
Run Code Online (Sandbox Code Playgroud)
我想知道如何传递a,b以及c相应的基类的构造函数.
谢谢,
我正在尝试使用另一个更通用的类方法定义一些类方法,如下所示:
class RGB(object):
def __init__(self, red, blue, green):
super(RGB, self).__init__()
self._red = red
self._blue = blue
self._green = green
def _color(self, type):
return getattr(self, type)
red = functools.partial(_color, type='_red')
blue = functools.partial(_color, type='_blue')
green = functools.partial(_color, type='_green')
Run Code Online (Sandbox Code Playgroud)
但当我尝试调用任何这些方法时,我得到:
rgb = RGB(100, 192, 240)
print rgb.red()
TypeError: _color() takes exactly 2 arguments (1 given)
Run Code Online (Sandbox Code Playgroud)
我想_color自从rgb.red(rgb)工作以来,自我没有被传递.
我正在尝试从扩展类访问父成员变量.但是运行以下代码......
class Mother(object):
def __init__(self):
self._haircolor = "Brown"
class Child(Mother):
def __init__(self):
Mother.__init__(self)
def print_haircolor(self):
print Mother._haircolor
c = Child()
c.print_haircolor()
Run Code Online (Sandbox Code Playgroud)
得到我这个错误:
AttributeError: type object 'Mother' has no attribute '_haircolor'
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
如果我有三个这样的课程:
class BaseClass(object):
def __init__(self, base_arg, base_arg2=None):
...
class MixinClass(object):
def __init__(self, mixin_arg):
...
class ChildClass(BaseClass, MixinClass):
def __init__(self, base_arg, mixin_arg, base_arg2=None):
???
Run Code Online (Sandbox Code Playgroud)
什么是初始化的正确方法MixinClass和BaseClass?
它看起来不像我可以使用,super因为它MixinClass和BaseClass两者都接受不同的参数......而且,两次调用,MixinClass.__init__(...)并且BaseClass.__init__(...),可能会导致钻石继承问题super被设计为阻止.
当从内置类型以及其他类派生时,似乎内置类型的构造函数不会调用超类构造函数.这导致__init__方法不会被调用MRO中内置之后的类型.
例:
class A:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
print("A().__init__()")
class B(list, A):
def __init__(self, *args, **kwargs):
print("B().__init__() start")
super().__init__(*args, **kwargs)
print("B().__init__() end")
if __name__ == '__main__':
b = B()
Run Code Online (Sandbox Code Playgroud)
在此示例中,永远不会调用A .__ init__.当B被定义为class B(A, list)相反 - 切换继承顺序 - 它按预期工作(即调用A .__ init__).
对继承顺序的这种非常微妙的依赖似乎是非pythonic的,它是这样的吗?这也意味着你必须永远不要从复杂类层次结构中的内置类型派生,因为当别人从你的类派生时(维护恐怖),你无法知道内置函数在MRO中的最终位置.我错过了什么吗?
额外信息:Python 3.1版
我经常看到自己必须在我的许多视图的上下文中添加相同的额外变量.
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super(MyListView, self).get_context_data(**kwargs)
# Add in the house
context['house'] = self.get_object().house
return context
Run Code Online (Sandbox Code Playgroud)
因为我不喜欢重复自己,我想我可以创建一个扩展视图的新类,然后我可以将所有视图基于新的扩展视图类.问题是,我使用了4类视图:CreateView,UpdateView,ListView和DeleteView.我是否真的必须为其中一个创建一个新类?
是不是像django"基础"视图类?也许更聪明的方法呢?提前谢谢了!
Python 2 documentation says that super() function "returns a proxy object that delegates method calls to a parent or sibling class of type."
The questions:
我的假设是给定类的兄弟是一个继承自同一父母的类.我起草了以下代码,以了解如何将方法调用委托给兄弟,但它不起作用.我做什么或理解错了什么?
class ClassA(object):
def MethodA(self):
print "MethodA of ClassA"
class ClassB(ClassA):
def MethodB(self):
print "MethodB of ClassB"
class ClassC(ClassA):
def MethodA(self):
super(ClassC, self).MethodA()
def MethodB(self):
super(ClassC, self).MethodB()
if __name__ == '__main__':
ClassC().MethodA() # Works as expected
# …Run Code Online (Sandbox Code Playgroud) python ×9
inheritance ×4
super ×4
oop ×3
class ×1
constructor ×1
django ×1
exception ×1
functools ×1
methods ×1
python-3.x ×1
scope ×1
siblings ×1