Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle in a better way decoration of class methods. #7

Open
LucaCappelletti94 opened this issue Mar 3, 2021 · 4 comments
Open

Handle in a better way decoration of class methods. #7

LucaCappelletti94 opened this issue Mar 3, 2021 · 4 comments

Comments

@LucaCappelletti94
Copy link
Collaborator

No description provided.

@ngast
Copy link

ngast commented Apr 13, 2021

I tried your method to cache some computation for a class but I does not seem to work for methods of an object:

from cache_decorator import Cache

class Foo():
    def __init__(self, bar):
        self.bar = bar
    
    @Cache()
    def my_bar(self):
        return self.bar

for i in [1, 2]:
    foo = Foo(i)
    print('I expect',i,'and print', foo.my_bar())

which prints

I expect 1 and print 1
I expect 2 and print 1

This seems to be fixable by adding something in the prefix.

@LucaCappelletti94
Copy link
Collaborator Author

Hello @ngast, as you have surely noticed this is a known issue that we are trying to understand how to solve best. The issue is that one solution may take the form of hashing the entire class (the self object) and that may include in some cases classes that are not hashable. Another solution may take the form of specifying which parameters of the class one may want to hash.

And yet another option is that users may be interested in altogether ignore the self method.
Another issue may be the interaction of the cached method with a possible child class. How should it behave in that case?

Could you share your opinion on this issue? We have been struggling for a while now about how to proceed to fix this.

@ngast
Copy link

ngast commented Apr 13, 2021

I am not sure if this would be the best option but the way I intended to do (before looking for an already existing solution) would have been to create a method for my class like "hash_of_instance(self)" that I would correspond to a hash of the interesting parameters. Then, I would concatenate this hash to the filename of the cache.

@zommiommy
Copy link
Owner

Hi, sorry for the long wait, we finally figured out how to properly handle methods.
From the new 2.1.0 version, you can either use in the path the instance attributes like:

class A:
    """Test that we can hash methods if self implements Hashable"""
    def __init__(self, x):
        self.x = x
    
    @Cache(
        cache_path="{cache_dir}/{a.name}_{self.x}.pkl",
        cache_dir="./test_cache",
        backup=False,
    )
    def cached_function(self, a):
        sleep(2)
        return [1, 2, 3]

Or you can implement your custom hash:

from dict_hash import Hashable

class B(Hashable):
    """Test that we can hash methods if self implements Hashable"""
    def __init__(self, x):
        self.x = x
    
    @Cache(
        cache_path="{cache_dir}/{a}_{_hash}.pkl",
        cache_dir="./test_cache",
        backup=False,
    )
    def cached_function(self, a):
        sleep(2)
        return [1, 2, 3]

    def consistent_hash(self) -> str:
        return str(self.x)

I hope this will solve this problem!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants