Python 哈希表的精简代理类

Python 哈希表的精简代理类,python,proxy-classes,Python,Proxy Classes,我需要某种瘦包装器对象来标记字典键,如: d = { Required('name'): str, Optional('age'): int, } 这些包装器的行为应该类似于包装对象(比较、散列等): 使用单个附加属性:它应该记住添加的类: isinstance(marked, Required) #-> True 并且添加的类应该具有自定义方法 这实际上有点像散列对象上的混合 我不喜欢那些模仿所有特殊属性的重量级拳手,而是想到以下想法: class Wrapper(obj

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

d = {
  Required('name'): str,
  Optional('age'): int,
}
这些包装器的行为应该类似于包装对象(比较、散列等):

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

isinstance(marked, Required)  #-> True
并且添加的类应该具有自定义方法

这实际上有点像散列对象上的混合


我不喜欢那些模仿所有特殊属性的重量级拳手,而是想到以下想法:

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)

更好的主意?

您的
包装器
类可以工作,是的。但是,如果您只需要一个包装器作为带有额外方法的替换键,那么我只需要创建一个专用类。这里显式比隐式好

此类只需代理和方法:

您可以根据需要向其中添加方法

演示:


是的,很简单,但是我还需要添加
\uuu repr\uuu()
\uu str\uuuu()
\uuu unicode\uuu()
,将来可能还会添加更多:)在这里,我要求一种通用的approach@kolypto:为什么要把它复杂化这么多?为了让它更友好,所以包装的值的行为与原始值一样。你不认为我的
type()
magic会像预期的那样工作吗?@MartijnPieters的解决方案满足了所有的需求,但它给类的用户留下了惊喜。例如,
marked!='name'
标记的
会产生令人惊讶的结果。@kolypto:当然,对于特殊的方法名称,您需要提供额外的代理或您自己的版本。但不要试图成为一切。
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)
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