Python中的继承,以便调用所有基函数
基本上,我想做的是:Python中的继承,以便调用所有基函数,python,inheritance,decorator,multiple-inheritance,Python,Inheritance,Decorator,Multiple Inheritance,基本上,我想做的是: class B: def fn(self): print 'B' class A: def fn(self): print 'A' @extendInherit class C(A,B): pass c=C() c.fn() 并且输出是 A B 如何实现extendInherit装饰器?我个人不会尝试使用装饰器来实现这一点,因为使用新样式的类和super可以实现以下功能: >>> class
class B:
def fn(self):
print 'B'
class A:
def fn(self):
print 'A'
@extendInherit
class C(A,B):
pass
c=C()
c.fn()
并且输出是
A
B
如何实现extendInherit装饰器?我个人不会尝试使用装饰器来实现这一点,因为使用新样式的类和super可以实现以下功能:
>>> class A(object):
... def __init__(self):
... super(A, self).__init__()
... print "A"
...
>>> class B(object):
... def __init__(self):
... super(B, self).__init__()
... print "B"
...
>>> class C(A, B):
... def __init__(self):
... super(C, self).__init__()
...
>>> foo = C()
B
A
我想方法调用也会以同样的方式工作。我个人不会尝试使用装饰器来实现这一点,因为使用新样式的类和super,可以实现以下功能:
>>> class A(object):
... def __init__(self):
... super(A, self).__init__()
... print "A"
...
>>> class B(object):
... def __init__(self):
... super(B, self).__init__()
... print "B"
...
>>> class C(A, B):
... def __init__(self):
... super(C, self).__init__()
...
>>> foo = C()
B
A
我想方法调用也会以同样的方式工作。这不是装饰者的工作。您希望完全改变类的正常行为,因此这实际上是元类的工作
import types
class CallAll(type):
""" MetaClass that adds methods to call all superclass implementations """
def __new__(meta, clsname, bases, attrs):
## collect a list of functions defined on superclasses
funcs = {}
for base in bases:
for name, val in vars(base).iteritems():
if type(val) is types.FunctionType:
if name in funcs:
funcs[name].append( val )
else:
funcs[name] = [val]
## now we have all methods, so decorate each of them
for name in funcs:
def caller(self, *args,**kwargs):
""" calls all baseclass implementations """
for func in funcs[name]:
func(self, *args,**kwargs)
attrs[name] = caller
return type.__new__(meta, clsname, bases, attrs)
class B:
def fn(self):
print 'B'
class A:
def fn(self):
print 'A'
class C(A,B, object):
__metaclass__=CallAll
c=C()
c.fn()
这不是装修工的工作。您希望完全改变类的正常行为,因此这实际上是元类的工作
import types
class CallAll(type):
""" MetaClass that adds methods to call all superclass implementations """
def __new__(meta, clsname, bases, attrs):
## collect a list of functions defined on superclasses
funcs = {}
for base in bases:
for name, val in vars(base).iteritems():
if type(val) is types.FunctionType:
if name in funcs:
funcs[name].append( val )
else:
funcs[name] = [val]
## now we have all methods, so decorate each of them
for name in funcs:
def caller(self, *args,**kwargs):
""" calls all baseclass implementations """
for func in funcs[name]:
func(self, *args,**kwargs)
attrs[name] = caller
return type.__new__(meta, clsname, bases, attrs)
class B:
def fn(self):
print 'B'
class A:
def fn(self):
print 'A'
class C(A,B, object):
__metaclass__=CallAll
c=C()
c.fn()
元类是一种可能的解决方案,但有点复杂。当然,super可以非常简单地使用新样式的类:没有理由在新代码中使用遗留类
class B(object):
def fn(self):
print 'B'
try: super(B, self).fn()
except AttributeError: pass
class A(object):
def fn(self):
print 'A'
try: super(A, self).fn()
except AttributeError: pass
class C(A, B): pass
c = C()
c.fn()
您需要try/except来支持单继承或多继承的任何顺序,因为在某个点上,在定义名为fn的方法的方法解析顺序MRO上将没有进一步的基础,您需要捕获并忽略结果AttributeError。但正如您所看到的,与您根据对不同答案的评论所想的不同,您不一定需要在最叶类中重写fn,除非您需要在这种重写中执行特定于该类的操作-超级在纯继承而非重写的方法上也可以很好地工作 元类是一种可能的解决方案,但有点复杂。当然,super可以非常简单地使用新样式的类:没有理由在新代码中使用遗留类
class B(object):
def fn(self):
print 'B'
try: super(B, self).fn()
except AttributeError: pass
class A(object):
def fn(self):
print 'A'
try: super(A, self).fn()
except AttributeError: pass
class C(A, B): pass
c = C()
c.fn()
您需要try/except来支持单继承或多继承的任何顺序,因为在某个点上,在定义名为fn的方法的方法解析顺序MRO上将没有进一步的基础,您需要捕获并忽略结果AttributeError。但正如您所看到的,与您根据对不同答案的评论所想的不同,您不一定需要在最叶类中重写fn,除非您需要在这种重写中执行特定于该类的操作-超级在纯继承而非重写的方法上也可以很好地工作 然而,在这里我仍然必须定义派生类中的每个函数。它们是单行函数,比如def fnself:super、self.fn,但我仍然需要为每个函数编写它。我正在寻找的是一种避免这种情况的方法。此外,为此,我必须使每个类都成为一个新样式的类。无论如何,您都应该使用新样式的类。Super是一个不错的选择。@Nikwin构造函数继承是python设计中没有的,因此如果您想在派生类中使用构造函数逻辑,是的,您必须显式调用构造函数。Explicit是python游戏的名称,我不能说我发现了一件坏事:@extraneon:我不担心构造函数,我想要的是派生类的函数调用所有同名的基类函数。但是,在这里我仍然必须定义派生类中的每个函数。它们是单行函数,比如def fnself:super、self.fn,但我仍然需要为每个函数编写它。我正在寻找的是一种避免这种情况的方法。此外,为此,我必须使每个类都成为一个新样式的类。无论如何,您都应该使用新样式的类。Super是一个不错的选择。@Nikwin构造函数继承是python设计中没有的,因此如果您想在派生类中使用构造函数逻辑,是的,您必须显式调用构造函数。Explicit是python游戏的名称,我不能说我发现了一件坏事:@extraneon:我不担心构造函数,我想要的是派生类的函数调用所有同名的基类函数。实际上,我更喜欢THC4k的解决方案随着OP的资格,他宁愿避免超级,这似乎更适合。然而,顺便说一句,元类只适用于新样式的类+尽管如此,对于nikow和extraneon来说,我还是更喜欢THC4k的解决方案随着OP的资格,他宁愿避免超级,这似乎更适合。然而,顺便说一句,元类只适用于新样式的类+然而,尼科和埃特莱昂的情绪都是如此。