首页 > 解决方案 > 如何“包装”对象以自动调用超类方法而不是覆盖方法?

问题描述

考虑:

class A(object):
    def f(self): print("A")

class B(A):
    def f(self): print("B")

b = B()

我可以A.f通过以下方式调用b

A.f(b)

有没有一种简单的方法来“包装”b这样wrap(b).f()需要A.fany f

标签: pythonpython-3.x

解决方案


这是我的解决方案,它从最上层的基类复制方法:

import types, copy

def get_all_method_names(clazz):
  return [func for func in dir(clazz) if callable(getattr(clazz, func))]

def wrap(obj):
  obj = copy.copy(obj)
  obj_clazz = obj.__class__
  base_clazz = obj_clazz.__bases__[-1] # the one which directly inherits from object
  base_methods = get_all_method_names(base_clazz) # list of all method names in base_clazz
  for base_method_name in base_methods:
    base_method = getattr(base_clazz, base_method_name) # get the method object
    if isinstance(base_method, types.FunctionType): # skip dunder methods like __class__, __init__
      setattr(obj, base_method_name, base_method) # copy it into our object
  return obj

# class declaration from question here

wrapped_b = wrap(b)

wrapped_b.f(wrapped_b) # prints A, unfortunately we have to pass the self parameter explicitly
b.f() # prints B, proof that the original object is untouched

推荐阅读