Hacker News new | ask | show | jobs
by sametmax 2581 days ago

   @ring.memcache(client, expire=60)   
   def get_url(url):
       return requests.get(url).content
can be written:

    def get_url(url):
        return requests.get(url).content

    get_url = ring.memcache(client, expire=60)(get_url)
Decorators are just syntactic sugar for that pattern.

You are then welcome to instantiate your ring.memcache object and bind it were it pleases you.

I would have provided a different API though:

   cache = pymemcache.client.Client(('127.0.0.1', 11211))

   @cache.lru(expire=60) # wrapper of ring.cache(client)
   def get_url(url):
       return requests.get(url).content
And accepted the alternative:

   cache = pymemcache.client.Client(conf_factory)

   def get_url(url):
       return requests.get(url).content

   get_url = cache.wraps.lru(get_url, expire=60)
  
It's better to not expect all people to know about the details of decorators just to use your API, and a factory is a nice hook to have anyway: it say where the code for that dynamic configuration should be and code as documentation is the best doc.

Also a patch() context manager would be nice for temporary caching:

   with cache.patch('module.lru', expire=60):
        get_url()
But it's hard to do in a thread safe way to compromised would have to be made.
1 comments

Although this is true, it is terrible from a developer UX perspective.

Yes, you can "dynamically"-decorate your functions at run-time using whatever global conditionals.

Yes, you can re-decorate the ring decorators.

But you shouldn't have to.

This design is guilty of the cardinal sin of being un-pythonic.

That's what I said. Read again.