Here is my code:
import os
import pickle
import hashlib
def read_file(path):
# Implement your read_file logic here
pass
def write_file(path, content):
# Implement your write_file logic here
pass
class CachedStaticMethod:
path = "cache"
def __init__(self, func):
self.func = func
def __get__(self, instance, owner):
if instance is None:
return self # Return the decorator instance for staticmethod to use
return self.func.__get__(instance, owner) # For regular methods
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(*args, **kwargs)
content = pickle.dumps(result)
write_file(cache_path, content)
return result
def __get_path(self, *args, **kwargs):
class_name = self.func.__qualname__.split('.<locals>', 1)[0]
function_name = self.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
# Usage
result1 = MyClass.my_static_method(5, "hello")
result2 = MyClass.my_static_method(5, "hello") # Should use cached result
print(result1)
print(result2)
This is the Error it's throwing:
AttributeError Traceback (most recent call last) in 54 55 # Usage ---> 56 result1 = MyClass.my_static_method(5, "hello") 57 result2 = MyClass.my_static_method(5, "hello") # Should use cached result 58
in call(self, *args, **kwargs) 23 24 def call(self, *args, **kwargs): ---> 25 cache_path = self.__get_path(*args, **kwargs) 26 27 try:
in __get_path(self, *args, **kwargs) 35 36 def __get_path(self, *args, **kwargs): ---> 37 class_name = self.func.qualname.split('.', 1)[0] 38 function_name = self.func.name 39
AttributeError: 'staticmethod' object has no attribute 'qualname'
This is a Python version issue. staticmethods don't have a
__qualname__
until Python 3.10.You could access the underlying function with
__func__
, but you're already implementing the descriptor protocol yourself, so it'd be easier to just not usestaticmethod
at all. Handlingstaticmethod
's functionality is straightforward and makes using your decorator simpler:Also, the way you've designed your
__get__
, you're only caching calls likeMyClass.my_static_method(...)
. Calls on an instance,MyClass().my_static_method(...)
, bypass the cache, even though they still don't receiveself
. You might want to just remove your__get__
entirely, so all calls use the cache.If you really want to keep
self.func
as a staticmethod, then you could doself.func.__func__.__qualname__
to get the qualname.