1

私は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
4

1 に答える 1

1

興味深い質問です。これが私がそれについて行く方法です。

(これは python2 で動作します。python3 ではテストしていませんが、動作しなくても驚かないでしょう...)

を使用してすべての「候補者」を反復処理し、 (反復子の値を取得することによって) 関連するを持っているという条件を満たすreversed(inspect.getmro(cls))最初のものを返すことができます。これは、関連する のメソッドと同じです。nextattrattrcls

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
于 2014-04-06T19:19:00.837 に答える