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

如何从静态方法的装饰器中获取类名?解决AttributeError报错

如何从静态方法的装饰器中获取类名?

问题重现

使用自定义缓存装饰器CachedStaticMethod装饰静态方法时,抛出如下错误:

AttributeError: 'staticmethod' object has no attribute 'qualname'

原因是装饰器接收的是staticmethod对象而非原始函数,该对象没有__qualname__属性,导致无法获取静态方法所属的类名。

解决方案

核心思路是利用描述器的__get__方法获取类对象(owner参数)并保存类名;同时通过staticmethod的__func__属性访问原始函数的信息,另外修正代码中的语法错误。

修正后的完整代码

import os
import pickle
import hashlib

def read_file(path):
    # 实现文件读取逻辑
    with open(path, 'rb') as f:
        return f.read()

def write_file(path, content):
    # 实现文件写入逻辑
    os.makedirs(os.path.dirname(path), exist_ok=True)
    with open(path, 'wb') as f:
        f.write(content)

class CachedStaticMethod:
    path = "cache"
    
    def __init__(self, func):
        self.func = func
        self.class_name = None  # 用于存储类名

    def __get__(self, instance, owner):
        if owner is not None:
            self.class_name = owner.__name__  # 获取并保存类名
        if instance is None:
            return self
        return self.func.__get__(instance, owner)

    def __call__(self, *args, **kwargs):
        cache_path = self.__get_path(*args, **kwargs)

        try:
            content = read_file(cache_path)
            result = pickle.loads(content)
        except Exception as e:
            # 调用静态方法包装的原始函数
            result = self.func.__func__(*args, **kwargs)
            content = pickle.dumps(result)
            write_file(cache_path, content)
        return result    

    def __get_path(self, *args, **kwargs):
        class_name = self.class_name
        # 通过__func__获取原始函数名称
        function_name = self.func.__func__.__name__
        
        # 修正编码语法错误
        hash_input = f"{class_name}.{function_name}({args}, {kwargs})".encode("utf-8")
        hash_value = hashlib.md5(hash_input).hexdigest()
        filename = f"{hash_value}.cache"
        return os.path.join(self.path, filename)

class MyClass:
    @CachedStaticMethod
    @staticmethod
    def my_static_method(param1: int, param2: str) -> float:
        """
        This is a cached static method of MyClass.
        """
        result = 3.14 * param1 + len(param2)
        return result

# 测试
result1 = MyClass.my_static_method(5, "hello")
result2 = MyClass.my_static_method(5, "hello")  # 第二次调用将使用缓存

print(result1)
print(result2)

关键改动说明

  1. 保存类名:在__get__方法中,通过owner.__name__直接获取类名并存储,后续生成缓存路径时直接调用。
  2. 访问原始函数:staticmethod对象的__func__属性指向被包装的原始函数,通过它可以获取函数名并执行实际逻辑。
  3. 修复语法错误:将原代码中错误的hash_input编码方式修正为.encode("utf-8")。
  4. 完善文件操作:补充了read_file和write_file的实际实现,确保缓存功能可以正常运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 08:37:06