hashables的瘦代理类

时间:2014-08-26 16:22:58

标签: python proxy-classes

我需要某种薄的包装器对象来标记字典键,例如:

d = {
  Required('name'): str,
  Optional('age'): int,
}

这些包装器应该像包装对象一样(比较,散列等):

marked = Required('name')
marked == 'name'  #-> True
d[marked] = 'hello'
d['name']  #-> 'hello'

使用一个附加属性:它应该记住添加的类:

isinstance(marked, Required)  #-> True

并且添加的类应该有自定义方法。

这实际上类似于可混合物体上的混合物。


我不喜欢那些模仿所有特殊属性并考虑以下想法的重量级Proxy Patterns

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)

更好的想法?

1 个答案:

答案 0 :(得分:5)

你的Wrapper课程会奏效,是的。但是,如果所有你想要的是一个包装器,可以作为替换键使用额外的方法,那么我只需创建一个专用的类。 显式优于隐式

此课程只需代理__eq____hash__方法:

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

您可以根据需要为此添加方法。

演示:

>>> marked = Required('name')
>>> marked == 'name'
True
>>> d = {}
>>> d[marked] = 'hello'
>>> d['name']
'hello'
>>> isinstance(marked, Required)
True