python 描述符 类方法 闭包

http://szhnet.iteye.com/blog/443469

# -*- 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()


1描述符 作为某一对象aa的属性被访问时, python会调用描述符的__get__方法   该对象aa会作为参数被隐示传入

2 但是以字典key访问时不会触发这个__get__方法

1 object_instance.descriptor_a  触发descriptor.__get__(self, object_instance) 返回一个bound方法(他有im_fun, im_self, im_class属性 可以用于区分一个方法是否为bound)

2 object_instance.__dict__['descriptor_a'] 则是直接返回一个描述符对象


所以monkey_patch  描述符如类方法 实例方法时

for field_name, value in object_a.__dict__.items():

if value.is_callable():

setattr(Item, fieldname, value) 而不是 getattr(object_a, name) 因为他返回的是一个bound的方法  而 value则是一个描述符对象




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值