Python:将函数作为类属性而非方法的调用错误解决方法
解决类属性存储外部函数时的
TypeError: unbound method问题 这个问题在Python 2里确实容易踩坑——当你把普通函数赋值给类属性时,Python会自动将其包装成未绑定方法(unbound method),这时候调用它就会要求你额外传入类或实例作为第一个参数,而你只是想把它当作普通函数使用,自然就触发了TypeError。
下面给你几个比用元组包裹更优雅的解决方案:
方案1:用staticmethod直接包装函数赋值
虽然你提到@staticmethod装饰器没法直接用于属性赋值,但我们可以直接用staticmethod()函数来包装外部函数后再赋值给类属性,这样就能绕开自动绑定的问题:
def f(x): print x class A: not_method = staticmethod(f) A.not_method(10) # 正常输出10
这个方案的好处是调用方式完全符合你的预期,不需要额外的索引操作,而且相当于明确告诉Python“这个属性不是方法,只是个普通函数”,比用元组包裹的写法更直观优雅。
方案2:直接访问未绑定方法的原始函数(不推荐)
如果你不想用staticmethod,也可以通过未绑定方法的__func__属性拿到原始函数来调用:
def f(x): print x class A: not_method = f A.not_method.__func__(10) # 输出10
不过这种方式依赖Python的内部实现细节,可读性差,不推荐在生产代码里这么写。
方案3:升级到Python 3(优先推荐,若可行)
如果你的项目可以升级到Python 3,那这个问题根本就不存在——Python 3取消了未绑定方法的概念,类属性里的普通函数直接就是原始函数,调用起来毫无问题:
def f(x): print(x) class A: not_method = f A.not_method(10) # 正常输出10
这是最彻底的解决方案,不需要修改任何代码逻辑,还能享受到Python 3的其他特性。
对比你之前用元组包裹的方式,上面的方案1和3都更符合Python的惯用写法,代码也更易读维护。
内容的提问来源于stack exchange,提问作者Anton Ovsyannikov
相关产品推荐
相关产品推荐

