|
|
|
|
|
by epper
5281 days ago
|
|
First time I write in HN, but I really wanted to give my take on this. I have to say that I really feel that to get readability, over nesting too, you often should refactor a bit the code. I would in fact write the get_cached_user method by using separate methods and a @cache decorator.
Every single function is very readable by itself. (I'm not fluent in python, pseudo-python follows... but you should get the idea) def cache(function_to_cache):
'''
A Decorator that caches a function result
'''
def wrapper(param):
cache_key = function_to_cache.name + " on " + param
if cache.contains(cache_key):
return cache.get(cache_key)
else
value = function_to_cache(param)
cache.set(cache_key, value)
return value
return wrapper
@cache
def get_cached_user_by_id(id):
return db.get_user_by_id(id)
@cache
def get_cached_user_by_username(username):
return db.get_user_by_username(username)
def get_cached_user(user_id = None, username = None):
user = None
if user_id:
user = get_cached_user_by_id(user_id)
else if username:
user = get_cached_user_by_username(username)
if not user:
raise ValueError('User not found')
return user
|
|
I think decorators are complex enough that I can't immediately look at the thing and know what its doing in the same way as early returns. A closure that takes a function pointer with some introspection magic is just a lot of mental juggling. At least with your case the complexity doesn't compound and is pushed as low as possible (as per Code Complete).
A final note: functions can have static members just like classes in python. fuction_to_cache.name would access the .name member of the function if such a thing existed (it will be an AttributeError? in this case). You are looking for function.__name__ I believe.