我们知道python的函数是描述符,unbound method和bound method都是instancemethod类型,是通过函数的__get__方法返回的。还有类方法classmethod也是instancemethod类型的。instancemethod用im_class,im_self和im_func保存了方法调用的相关信息。静态方法staticmethod其实返回的就是函数本身。知道了这些之后可以自己用python来做个这些函数或方法的实现。
# -*- coding:utf-8 -*- #
class FunWrap(object):
u"""包装一个函数"""
def __init__(self, func):
self.func = func
def __get__(self, obj, typ = None):
return szhinstancemethod(typ, obj, self)
def __call__(self, *args):
return self.func(*args)
def __getattr__(self, name):
return getattr(self.func, name)
class szhinstancemethod(object):
u"""模拟instancemethod"""
def __init__(self, im_class, im_self, im_func):
self.im_class = im_class
self.im_self = im_self
self.im_func = im_func
def __call__(self, *args):
if not self.im_self:
raise TypeError, "unbound method " + self.im_funcw.func_name + \
"() must be called with " + \
(self.im_class.__name__ if self.im_class else '?') + " instance"
return self.im_func(self.im_self, *args)
def __repr__(self):
if not self.im_self:
return '<unbound method ' + (self.im_class.__name__ if self.im_class else '?') \
+ "." + self.im_func.func_name + "> __szh"
else:
return '<bound method ' + (self.im_class.__name__ if self.im_class else '?') \
+ "." + self.im_func.func_name + " of " + str(self.im_self) + "> __szh"
class szhclassmethod(object):
u"""模拟classmethod"""
def __init__(self, func):
self.func = func
def __get__(self, obj, typ = None):
typ = typ or type(obj)
return szhinstancemethod(type(typ), typ, self.func)
class szhstaticmethod(object):
u"""模拟staticmethod"""
def __init__(self, func):
self.func = func
def __get__(self, obj, typ = None):
return self.func
if __name__ == '__main__':
class A(object):
@FunWrap
def f(self):
print 'test method ' + str(self)
@szhclassmethod
@FunWrap
def clsf(cls):
print 'test class method ' + str(cls)
@szhstaticmethod
@FunWrap
def staf():
print 'test static method'
a = A()
a1 = A()
print u"实例a访问方法f",a.f
print u"实例a1访问方法f",a1.f
print u"类A访问方法f",A.f
a.f()
a1.f()
print u"实例a访问类方法clasf",a.clsf
print u"类A访问类方法clasf",A.clsf
A.clsf()
a.clsf()
print u"实例a访问静态方法staf",a.staf
print u"类A访问静态方法staf",A.staf
a.staf()