这是使用元类魔法的一种方法;恕我直言,它比其他方法更健壮和灵活,它还可以Bar.write(x, "hello")
正确处理无界调用(例如)和单继承(参见下面的 Baz):
class ReverserMetaclass(type):
def __new__(cls, name, bases, dct):
""" This metaclass replaces methods of classes made from it
with a version that first calls their base classes
"""
# create a new namespace for the new class
new_dct = {}
for member_name, member in dct.items():
# only decorate methods/callable in the new class
if callable(member):
member = cls.wrap(bases, member_name, member)
new_dct[member_name] = member
# construct the class
return super(ReverserMetaclass, cls).__new__(cls, name, bases, new_dct)
# instead of the above, you can also use something much simpler
# dct['read'] = cls.wrap(bases, 'read', dct['read'])
# return super(ReverserMetaclass, cls).__new__(cls, name, bases, dct)
# if you have a specific method that you want to wrap and want to
# leave the rest alone
@classmethod
def wrap(cls, bases, name, method):
""" this method calls methods in the bases before calling the method """
def _method(*args, **kwargs):
for base in bases:
if hasattr(base, name):
getattr(base, name)(*args, **kwargs)
# put this above the loop if you want to reverse the call order
ret = method(*args, **kwargs)
return ret
return _method
示例控制台运行:
>>> class Foo(object):
... __metaclass__ = ReverserMetaclass
... def write(self, s=""):
... # Make sure that overwritten
... # 'write' method in child class
... # does what it's specified, and
... # then what comes next...
... print "Write - From Foo", s
... def read(self):
... print "Read - From Foo"
...
>>> class Bar(Foo):
... def write(self, s=""):
... print "Write - from Bar", s
... def read(self):
... print "Read - From Bar"
...
>>> class Baz(Bar):
... def write(self, s=""):
... print "Write - from Baz", s
...
>>> x = Bar()
>>> x.write("hello")
Write - From Foo hello
Write - from Bar hello
>>> Bar.read(x)
Read - From Foo
Read - From Bar
>>>
>>> x = Baz()
>>> x.read()
Read - From Foo
Read - From Bar
>>> x.write("foo")
Write - From Foo foo
Write - from Bar foo
Write - from Baz foo
Python 元类非常强大,尽管正如其他人所说,你真的不想太频繁地使用这种魔法。