got*_*nes 5 python abstract-class super
抽象基类在Python中仍然可以派上用场.在编写一个抽象基类,我希望每个子类都有一个spam()方法,我想写这样的东西:
class Abstract(object):
def spam(self):
raise NotImplementedError
Run Code Online (Sandbox Code Playgroud)
挑战还包括想要使用super(),并通过将其包含在整个子类链中来正确地完成.在这种情况下,似乎我必须super包括如下所示的每个调用:
class Useful(Abstract):
def spam(self):
try:
super(Useful, self).spam()
except NotImplementedError, e:
pass
print("It's okay.")
Run Code Online (Sandbox Code Playgroud)
这对于一个简单的子类来说没问题,但是当编写一个有很多方法的类时,try-except会变得有点麻烦,而且有点难看.是否有更优雅的抽象基类子类化方法?我只是做错吗?
您可以使用abc模块在python 2.6+中干净地完成此操作:
import abc
class B(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def foo(self):
print 'In B'
class C(B):
def foo(self):
super(C, self).foo()
print 'In C'
C().foo()
Run Code Online (Sandbox Code Playgroud)
输出将是
In B
In C
Run Code Online (Sandbox Code Playgroud)
理解这一点的关键是super()为了实现合作继承。类如何合作取决于程序员。super()不是魔法,不知道你到底想要什么!对于不需要协作继承的平面层次结构使用 super 没有多大意义,因此在这种情况下,S. Lott 的建议是正确的。Useful 的子类可能想使用也可能不想使用super(),具体取决于他们的目标:)
例如:摘要是 A。A <- B,但是您希望支持 C 的插入,如 A <- C <- B。
class A(object):
"""I am an abstract abstraction :)"""
def foo(self):
raise NotImplementedError('I need to be implemented!')
class B(A):
"""I want to implement A"""
def foo(self):
print('B: foo')
# MRO Stops here, unless super is not A
position = self.__class__.__mro__.index
if not position(B) + 1 == position(A):
super().foo()
b = B()
b.foo()
class C(A):
"""I want to modify B and all its siblings (see below)"""
def foo(self):
print('C: foo')
# MRO Stops here, unless super is not A
position = self.__class__.__mro__.index
if not position(C) + 1 == position(A):
super().foo()
print('')
print('B: Old __base__ and __mro__:\n')
print('Base:', B.__bases__)
print('MRO:', B.__mro__)
print('')
# __mro__ change implementation
B.__bases__ = (C,)
print('B: New __base__ and __mro__:\n')
print('Base:', B.__bases__)
print('MRO:', B.__mro__)
print('')
b.foo()
Run Code Online (Sandbox Code Playgroud)
和输出:
B: foo
B: Old __base__ and __mro__:
Base: (<class '__main__.A'>,)
MRO: (<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
B: New __base__ and __mro__:
Base: (<class '__main__.C'>,)
MRO: (<class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
B: foo
C: foo
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12125 次 |
| 最近记录: |