You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中为@staticmethod绑定属性后无法访问的问题

问题原因及解决办法

原因分析

  • staticmethod装饰器返回的是类实例:用@staticmethod装饰hello_fn后,得到的不是原函数本身,而是staticmethod类的对象。你在build_hello里给这个staticmethod实例添加了first_name属性,此时调用hello_fn()能正常执行,是因为staticmethod实现了__call__方法,会自动委托调用底层的原函数。
  • 类属性访问触发描述符逻辑:当把staticmethod实例赋值给类变量后,通过World.hello_fn访问时,会触发staticmethod的__get__方法(它是Python的描述符),这个方法会返回底层的原函数,而非你添加了属性的staticmethod实例。由于first_name属性绑定在staticmethod实例上,不在原函数上,所以外部访问时找不到该属性。

解决方案

方法一:先给原函数加属性,再用装饰器包装(推荐)

调整build_hello的执行顺序,先给未装饰的原函数绑定属性,再用staticmethod包装,这样属性会保留在原函数上,通过类访问时就能正常获取:

def build_hello(name: str):
    def hello_fn():
        return "hello my name is "
    # 先给原函数绑定属性
    hello_fn.first_name = name
    # 再用staticmethod装饰
    static_hello = staticmethod(hello_fn)
    print(static_hello() + hello_fn.first_name)
    return static_hello

class World:
    hello_fn = build_hello("bob")

# 正常访问属性
print(World.hello_fn.first_name)  # 输出: bob

方法二:直接获取类中的staticmethod实例(不推荐)

如果不想修改build_hello的结构,可以通过类的__dict__直接获取原始的staticmethod实例(绕过描述符的__get__逻辑):

# 针对你原本的代码,这样能访问到属性
print(World.__dict__['hello_fn'].first_name)  # 输出: bob

这种方式属于取巧写法,可读性和维护性较差,优先推荐方法一。

内容的提问来源于stack exchange,提问作者Coldchain9

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 10:12:40