Skip to content

Instantly share code, notes, and snippets.

@podhmo
Created August 16, 2013 13:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save podhmo/6250117 to your computer and use it in GitHub Desktop.
Save podhmo/6250117 to your computer and use it in GitHub Desktop.
# -*- coding:utf-8 -*-
## why define like a this?
def _get_getter(o, attribute_string):
return lambda : _getter(o, attribute_string)
def _getter(o, attribute_string):
for k in attribute_string.split("."):
o = getattr(o, k)
return o
class a:
class b:
c = 10
assert _get_getter(a, "b.c")() == 10
## not _get_target(a, "b.c") == 10?
## answer 1.a
# another object uses this, with default value
class AccessObject(object):
def __init__(self, default):
self.default = default
def __call__(self, getter):
try:
return getter()
except (KeyError, AttributeError):
return self.default
getter = _get_getter(a, "b.c")
AccessObject(None)(getter) == 10
getter = _get_getter(a, "b.c.d.e")
AccessObject(None)(getter) == None
## answer 1.b
# if access cost is huge and cacheable.
class CachedAccess(object):
def __init__(self, keyfn=id):
self.cache = {}
self.keyfn = keyfn
def __call__(self, getter):
k = self.keyfn(getter)
if k in self.cache:
return self.cache[k]
v = self.cache[k] = getter()
return v
cached_access = CachedAccess()
getter = _get_getter(a, "b.c")
default_getter = lambda : AccessObject(None)(getter)
cached_access(default_getter)
cached_access(default_getter)
cached_access(default_getter)
getter = _get_getter(a, "b.c.d.e")
default_getter = lambda : AccessObject(None)(getter)
cached_access(default_getter)
cached_access(default_getter)
cached_access(default_getter)
## answer 2
# another getter is defined.
def _get_dict_getter(D, attribute_string):
return lambda : _dict_getter(D, attribute_string)
def _dict_getter(D, attribute_string):
for k in attribute_string.split("."):
D = D[k]
return D
D = {"x": {"y": {"z": 100}}}
class a:
class b:
c = 10
access = AccessObject(None)
getters = [_get_dict_getter(D, "x.y.z"), _get_getter(a, "b.c"), _get_getter(a, "x.y.z")]
assert [access(e) for e in getters] == [100, 10, None]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment