I need some kind of thin wrapper object to mark dictionary keys, like:
d = {
Required('name'): str,
Optional('age'): int,
}
And these wrappers should behave like the wrapped object (comparison, hashing, etc):
marked = Required('name')
marked == 'name' #-> True
d[marked] = 'hello'
d['name'] #-> 'hello'
With a single additional property: it should remember the added class:
isinstance(marked, Required) #-> True
and the added class should have custom methods.
This is actually something like a mixin on hashable objects.
I dislike those heavyweight Proxy Patterns which mimic all special properties and thinking of the following idea instead:
class Wrapper(object):
def __new__(cls, value):
value_type = type(value)
Type = type(
value_type.__name__, # same name
(cls, value_type), # Wrapper + bases
{})
Type.__new__ = value_type.__new__ # prevent recursion
return Type(value)
# Override method
def __repr__(self):
return 'Wrapper({})'.format(self)
Better ideas?
Your Wrapper
class will work, yes. However, if all you wanted is a wrapper to act as a substitute key with extra methods, then I'd just create a dedicated class instead. Explicit is better than implicit here.
This class only has to proxy the __eq__
and __hash__
methods:
class HashableProxy(object):
def __init__(self, wrapped):
self._wrapped = wrapped
def __eq__(self, other):
return self._wrapped == other
def __hash__(self):
return hash(self._wrapped)
class Required(HashableProxy):
pass
class Optional(HashableProxy):
pass
You can add methods to this as required.
Demo:
>>> marked = Required('name')
>>> marked == 'name'
True
>>> d = {}
>>> d[marked] = 'hello'
>>> d['name']
'hello'
>>> isinstance(marked, Required)
True