除了重载或新定义的方法之外,我想告诉继承的方法。这可能与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'
是否存在类似示例中的“魔术方法”,或者某种方式将这些类型的方法实现区分开来?
答案 0 :(得分:17)
我不确定这是个好主意,但您可以使用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'
答案 1 :(得分:7)
如果你了解祖先,你可以简单地测试一下:
>>> B.spam == A.spam
False
>>> B.ham == A.ham
True
要查找所有基类的列表,请查看此处:List all base classes in a hierarchy of given class?
我还要指出,如果你需要这个,你的班级设计可能是错的。你不应该关心OOP中的这些东西(除非你正在创建一个对象检查器或类似的东西)。
答案 2 :(得分: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'
"""}
答案 3 :(得分:1)
扩大hamstergene的答案;类将其基类存储在类变量__bases__
中。
所以:
>>> B.spam == B.__bases__[0].spam
False
>>> B.ham == B.__bases__[0].ham
True
>>> B.eggs == B.__bases__[0].eggs
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'A' has no attribute 'eggs'
>>> hasattr(B,"eggs")
True
>>> hasattr(B.__bases__[0],"eggs")
False
答案 4 :(得分:1)
对于新式类,您有一个方法mro()
,返回方法结果顺序列表。 [0]
是班级本身。
所以你可以做到
>>> any(hasattr(i, 'ham') for i in B.mro()[1:])
True
>>> any(hasattr(i, 'spam') for i in B.mro()[1:])
True
>>> any(hasattr(i, 'eggs') for i in B.mro()[1:])
False
所以eggs
是新定义的。
>>> any(getattr(B, 'ham') == getattr(i, 'ham', None) for i in B.mro()[1:])
True
>>> any(getattr(B, 'spam') == getattr(i, 'spam', None) for i in B.mro()[1:])
False
所以ham
是继承的。
通过这些,您可以制作自己的启发式方法。