有没有办法在Python中识别继承的方法?
我想将继承的方法与重载或新定义的方法区分开来。Python能做到这一点吗 例如:有没有办法在Python中识别继承的方法?,python,inheritance,Python,Inheritance,我想将继承的方法与重载或新定义的方法区分开来。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' 所需功能: >&
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'
有没有像示例中那样的“神奇方法”,或者有什么方法可以区分这些类型的方法实现?如果您知道祖先,您可以简单地测试:
>>> B.spam == A.spam
False
>>> B.ham == A.ham
True
要查找所有基类的列表,请查看以下内容:
我还要指出,如果你需要这个,你的类设计可能是错误的。在OOP中,您不应该关心这些事情(除非您正在创建对象检查器或类似的东西)。我不确定这是一个好主意,但您可能可以使用
hasattr
和\u dict\u
来完成
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'
扩展了hamstergene的答案;类将其基类存储在类变量
中
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'
因此:
>>B.spam==B.\uuuu基\uuuu[0]。spam
假的
>>>B.ham==B.。\uuuuu基[0]。ham
真的
>>>B.eggs==B.。\uuuuu碱基\uuuuuu[0]。鸡蛋
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
AttributeError:类型对象“A”没有属性“eggs”
>>>hasattr(B,“蛋”)
真的
>>>hasattr(B.“碱基”[0],“蛋”)
假的
通常的方法是(python 2.*):
对于新样式的类,您有一个方法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
因此,egs
是新定义的
>>> 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
是继承的
有了这些,你就可以设计自己的启发式方法。这在OOP中是一个奇怪的要求,这是一种特殊情况,在这种情况下,可能需要扩展对象而不需要子类化。我必须检查是否可以简单地重写其中一个方法,或者是否必须保留已存在的重写方法。是的,它在某种程度上是一个对象检查器,即使不是为了调试/分析目的。我意识到这可能并不总是一个好主意,但我认为在这种情况下,这是合理的。感谢您指出可能的设计错误。hasattr(super(clazz),method)仅适用于方法,因为super(clazz)为该类的方法返回一个代理类。e、 g.类属性不是代理类的一部分
>>> 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