如何为Python函数对象设置类实例式属性?
Python函数对象能否像类实例那样直接调用属性(而非调用方法)?
问题描述
你希望给Python函数对象赋值属性后,直接通过my_func.prop触发该属性函数的执行,而非必须使用my_func.prop()调用。期望实现的效果如下:
def prop(): print("I am a property") def my_func(): print("Just a function call") my_func.prop = prop my_func.prop # 期望这里直接打印 'I am a property'
目前只能通过my_func.prop()调用该属性,尝试给函数类附加属性时:
setattr(my_func.__class__, "prop", property(prop))
出现报错:
TypeError: cannot set 'prop' attribute of immutable type 'function'
可行解决方案
方案1:包装函数为自定义类实例
原生function类型是不可变的,无法直接修改其类行为,所以可以把函数包装成自定义类的实例,灵活控制属性访问:
def prop(): print("I am a property") def my_func(): print("Just a function call") class FunctionWrapper: def __init__(self, func): self._func = func # 复制原函数的所有属性 self.__dict__.update(func.__dict__) def __call__(self): # 保留原函数的调用能力 return self._func() def __getattribute__(self, name): try: # 优先获取包装类自身的属性 attr = super().__getattribute__(name) except AttributeError: # 找不到则从原函数的属性中获取 attr = self._func.__dict__.get(name) # 如果属性是可调用对象,直接执行并返回结果 if callable(attr): return attr() return attr # 用包装类替换原函数 my_func = FunctionWrapper(my_func) my_func.prop = prop # 测试效果 my_func() # 输出: Just a function call my_func.prop # 输出: I am a property
方案2:使用描述符实现单个属性的自动调用
如果不想包装整个函数,可以给目标属性定义描述符,实现访问时自动执行:
def prop(): print("I am a property") def my_func(): print("Just a function call") class CallOnAccess: def __init__(self, func): self.func = func def __get__(self, instance, owner): # 当访问属性时自动执行函数 return self.func() # 给my_func添加带描述符的属性 my_func.prop = CallOnAccess(prop) # 测试 my_func.prop # 输出: I am a property my_func() # 输出: Just a function call
为什么原生function类无法修改?
Python内置的function属于不可变类型,其类结构不允许动态添加或修改属性,这是语言层面的限制,所以直接修改function类会抛出TypeError。
内容的提问来源于stack exchange,提问作者GopherM
相关产品推荐
相关产品推荐

