在django.utils.functional.py:
for t in type(res).mro(): # <----- this
if t in self.__dispatch:
return self.__dispatch[t][funcname](res, *args, **kw)
Run Code Online (Sandbox Code Playgroud)
我不明白mro().它是做什么的,"mro"是什么意思?
在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.
这是我计划用于游戏的代码.但它抱怨MRO错误.我不知道为什么.有人能为我解释一下吗?非常感谢.
class Player:
pass
class Enemy(Player):
pass
class GameObject(Player, Enemy):
pass
g = GameObject()
Run Code Online (Sandbox Code Playgroud) 说,我有以下mixin通过触摸相互重叠dispatch():
class FooMixin(object):
def dispatch(self, *args, **kwargs):
# perform check A
...
return super(FooMixin, self).dispatch(*args, **kwargs)
class BarMixin(object):
def dispatch(self, *args, **kwargs):
# perform check B
...
return super(FooMixin, self).dispatch(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
如果我希望我的视图通过订单,请检查A - >检查B,如果我的代码是MyView(FooMixin, BarMixin, View)或者MyView(BarMixin, FooMixin, View)?
为什么我们总是View在mixins之后放入或者它的子类?(我从阅读django通用视图的源代码中注意到了这一点,但我不知道它背后的基本原理,如果有的话)
python django django-views method-resolution-order django-class-based-views
当从内置类型以及其他类派生时,似乎内置类型的构造函数不会调用超类构造函数.这导致__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版
在Raymond Hettinger 在PyCon 2015上的演讲" 超级考虑超级发言 "中,他解释了super在多重继承环境中使用Python 的优势.这是雷蒙德在演讲中使用的一个例子:
class DoughFactory(object):
def get_dough(self):
return 'insecticide treated wheat dough'
class Pizza(DoughFactory):
def order_pizza(self, *toppings):
print('Getting dough')
dough = super().get_dough()
print('Making pie with %s' % dough)
for topping in toppings:
print('Adding: %s' % topping)
class OrganicDoughFactory(DoughFactory):
def get_dough(self):
return 'pure untreated wheat dough'
class OrganicPizza(Pizza, OrganicDoughFactory):
pass
if __name__ == '__main__':
OrganicPizza().order_pizza('Sausage', 'Mushroom')
Run Code Online (Sandbox Code Playgroud)
有人在台下问雷蒙德有关使用的差异self.get_dough(),而不是super().get_dough().我对Raymond的简要回答并不是很了解,但我编写了这个例子的两个实现来看看差异.两种情况的输出相同:
Getting dough
Making pie with pure untreated wheat dough
Adding: Sausage
Adding: …Run Code Online (Sandbox Code Playgroud) super()直接使用和使用父类名称有区别吗?例如:
class Parent:
def __init__(self):
print("In parent")
self.__a=10
class Child(Parent):
def __init__(self):
super().__init__() # using super()
Parent.__init__(self) # using Parent class name
c=Child()
Run Code Online (Sandbox Code Playgroud)
是否有内部之间的差异super().__init__()和Parent.__init__(self)?
python inheritance initialization super method-resolution-order
考虑这个例子,其中子类有一个没有签名的multi方法和一个带有slurpy参数的方法:
class Foo {
multi method do-it { put "Default" }
multi method do-it ( Int $n ) { put "Int method" }
multi method do-it ( Str $s ) { put "Str method" }
multi method do-it ( Rat $r ) { put "Rat method" }
}
class Bar is Foo {
multi method do-it { put "Bar method" }
multi method do-it (*@a) { put "Bar slurpy method" }
}
Foo.new.do-it: 1;
Foo.new.do-it: 'Perl 6';
Foo.new.do-it: <1/137>;
Foo.new.do-it; …Run Code Online (Sandbox Code Playgroud) 考虑以下类层次结构:
如何确定在C++中对类X的对象调用foo()时将执行哪个方法?
(我正在寻找算法,而不是任何特定情况.)
c++ multiple-inheritance virtual-inheritance method-resolution-order
假设你有类似的东西
class C2: pass
class C1(object): pass
class B2: pass
class B1(C1, C2): pass
class A(B1,B2): pass
Run Code Online (Sandbox Code Playgroud)
当您具有混合层次结构时,python如何相对于继承和方法解析顺序?它是否遵循旧的遍历,新的遍历,两者的混合取决于层次结构的哪个分支行走?
python ×8
inheritance ×3
super ×2
c++ ×1
constructor ×1
django ×1
django-views ×1
multimethod ×1
perl6 ×1
python-3.x ×1
raku ×1
self ×1
typeerror ×1