有没有办法在Python中识别继承的方法?
我想区分一下继承的方法和重载或新定义的方法。在Python中,这可能吗?
举个例子:
class A(object):
def spam(self):
print 'A spam'
def ham(self):
print 'A ham'
class B(A):
def spam(self):
print 'Overloaded spam'
def eggs(self):
print 'Newly defined eggs'
我想要的功能:
>>> magicmethod(B.spam)
'overloaded'
>>> magicmethod(B.ham)
'inherited'
>>> magicmethod(B.eggs)
'newly defined'
有没有什么“魔法方法”,或者其他方法可以帮助我区分这些不同类型的方法实现呢?
5 个回答
6
一种通用的方法是(适用于 Python 2.*):
def _getclass(method):
try:
return method.im_class
except AttributeError:
return method.__class__
def magicmethod(method):
method_cls = _getclass(method)
if method.__name__ not in method_cls.__dict__:
return 'inherited'
for cls in method_cls.__mro__[1:]:
if method.__name__ in cls.__dict__:
return 'overloaded'
return 'newly defined'
__test__ = {"example": """
>>> class A(object):
... def spam(self):
... print 'A spam'
... def ham(self):
... print 'A ham'
>>> class B(A):
... def spam(self):
... print 'Overloaded spam'
... def eggs(self):
... print 'Newly defined eggs'
>>> magicmethod(B.spam)
'overloaded'
>>> magicmethod(B.ham)
'inherited'
>>> magicmethod(B.eggs)
'newly defined'
>>> magicmethod(B.__init__)
'inherited'
"""}
8
如果你知道祖先类,可以直接测试一下:
>>> B.spam == A.spam
False
>>> B.ham == A.ham
True
想要查看所有基类的列表,可以去这里看看:列出给定类的所有基类?
我还想提醒你,如果你需要这样做,可能说明你的类设计有问题。在面向对象编程中,你不应该太在意这些事情(除非你是在做一个对象检查器之类的工具)。
21
我不太确定这样做是否合适,但你可能可以通过使用 hasattr
和 __dict__
来实现。
def magicmethod(clazz, method):
if method not in clazz.__dict__: # Not defined in clazz : inherited
return 'inherited'
elif hasattr(super(clazz), method): # Present in parent : overloaded
return 'overloaded'
else: # Not present in parent : newly defined
return 'newly defined'