私は2つのクラスを持っています:
class A(object):
def a(self):
pass
class B(A):
def b(self):
pass
print dir(A)
print dir(B)
Pythonでどのクラスメソッドが派生したかを確認するにはどうすればよいですか?
例えば:
getMethodClass(A.a) == A
getMethodClass(B.a) == A
getMethodClass(B.b) == B
私は2つのクラスを持っています:
class A(object):
def a(self):
pass
class B(A):
def b(self):
pass
print dir(A)
print dir(B)
Pythonでどのクラスメソッドが派生したかを確認するにはどうすればよいですか?
例えば:
getMethodClass(A.a) == A
getMethodClass(B.a) == A
getMethodClass(B.b) == B
興味深い質問です。これが私がそれについて行く方法です。
(これは python2 で動作します。python3 ではテストしていませんが、動作しなくても驚かないでしょう...)
を使用してすべての「候補者」を反復処理し、 (反復子の値を取得することによって) 関連するを持っているという条件を満たすreversed(inspect.getmro(cls))
最初のものを返すことができます。これは、関連する のメソッドと同じです。next
attr
attr
cls
im_func
メソッド同一性比較は、バインドされていないメソッドの属性を比較することによって行われます。
import inspect
def getMethodClass(cls, attr):
return next(
basecls for basecls in reversed(inspect.getmro(cls))
if hasattr(basecls, attr)
and getattr(basecls, attr).im_func is getattr(cls, attr).im_func
)
getMethodClass(A, 'a')
=> __main__.A
getMethodClass(B, 'a')
=> __main__.A
getMethodClass(B, 'b')
=> __main__.B
# an alternative implementation, suggested by @chameleon
def getAttributeClass(cls, attrName):
# check first if has attribute
attr = getattr(cls, attrName)
mro = inspect.getmro(cls)
# only one class on list
if len(mro) == 1:
return cls
# many class on list
for base in reversed(mro[1:]):
# check if defined in this base
try:
baseAttr = getattr(base, attrName)
except AttributeError:
continue
else:
if baseAttr.im_func is attr.im_func:
return base
# define in top class
return cls
関数には、提案した署名を含めることもできます。
def getMethodClass(unbound_method):
cls = unbound_method.im_class
attr = unbound_method.__name__
# rest of implementation is the same as before...
getMethodClass(B.a)
=> __main__.A