Python中的Ruby Mash等价物?

Python中的Ruby Mash等价物?,python,ruby,mocking,Python,Ruby,Mocking,在Ruby中,有一个很棒的库称为a,它是一个散列,但通过巧妙地使用missing_方法可以转换: object['property'] 到 这对于模拟非常有用。有人知道Python中类似的东西吗 你在找什么 class C: def __init__(self): self.my_property = "Hello" def __getitem__(self, name): return getattr(self, name) c = C() print

在Ruby中,有一个很棒的库称为a,它是一个散列,但通过巧妙地使用missing_方法可以转换:

object['property']


这对于模拟非常有用。有人知道Python中类似的东西吗

你在找什么

class C:
   def __init__(self):
      self.my_property = "Hello"

   def __getitem__(self, name):
      return getattr(self, name)

c = C()
print c['my_property']  # Prints "Hello"
或者,您是否正在通过
\uuu getattr\uuuu
寻找相反的结果

class D(dict):
   def __getattr__(self, name):
      return self[name]

d = D()
d['x'] = "Hello"
print d.x  # Prints "Hello"

Edit:正如Paul McGuire在评论中善意地指出的那样,此代码仅演示了完整解决方案的基本内容。)

您是否绝对有必要将其基于dict?Python对象可以通过很少的额外管道动态获取属性:

>>> class C(object): pass
...
>>> z = C()
>>> z.blah = "xyzzy"
>>> dir(z)
['__class__', '__delattr__', '__dict__', ... '__weakref__', 'blah']

你是否绝对有必要根据口述来做这件事

如果您希望将其视为一个项目列表,而不滥用
\uuu dict\uuu
,则选择“是”

下面是我对Mash问题的老答案。它提供了一个默认值,默认值可能是一个方法或一个对象,如果它是一个对象,如果它被多次使用,它将进行深度克隆(不仅仅是热链接)

并将其简单键值公开为
。key

def Map(*args, **kwargs):
    value = kwargs.get('_default', None)
    if kwargs.has_key('_default'):  del kwargs['_default']

 # CONSIDER  You may want to look at the collections.defaultdict class.
 #      It takes in a factory function for default values.
 #
 # You can also implement your class by overriding the __missing__ method
 #      of the dict class, rather than overriding the __getitem__.
 #
 # Both were added in Python 2.5 according to the documentation.

    class _DefMap(dict):
        'But CONSIDER http://pypi.python.org/pypi/bunch/1.0.0 '

        def __init__(self, *a, **kw):
            dict.__init__(self, *a, **kw)
            self.__dict__ = self

        def __getitem__(self, key):

            if not self.has_key(key):

                if hasattr(value, '__call__'):
                    self[key] = value(key)
                else:
                    self[key] = copy.deepcopy(value)

            return dict.__getitem__(self, key)

    return _DefMap(*args, **kwargs)

看这里。您还可以将dict转换为mash对象。

为了更完整的属性模拟,还可以实现
\uuuuu dir\uuuu
以返回所有dict的属性,以及所有用户指定的名称。将与dict自己的属性冲突,如项、值等。因为
\uuuu getattr\uuuuu
仅在未找到属性时才会被调用。因此,可以设置d['items',但此
\uuu getattr\uuu
永远无法检索。为了解决这个问题,编写D来包含并委托给dict,而不是从dict继承。最后,OP正在尝试编写mock,因此
\uuuuuuu setattr\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu!对于如此快速的回答,我也愿意多加分数:)
def Map(*args, **kwargs):
    value = kwargs.get('_default', None)
    if kwargs.has_key('_default'):  del kwargs['_default']

 # CONSIDER  You may want to look at the collections.defaultdict class.
 #      It takes in a factory function for default values.
 #
 # You can also implement your class by overriding the __missing__ method
 #      of the dict class, rather than overriding the __getitem__.
 #
 # Both were added in Python 2.5 according to the documentation.

    class _DefMap(dict):
        'But CONSIDER http://pypi.python.org/pypi/bunch/1.0.0 '

        def __init__(self, *a, **kw):
            dict.__init__(self, *a, **kw)
            self.__dict__ = self

        def __getitem__(self, key):

            if not self.has_key(key):

                if hasattr(value, '__call__'):
                    self[key] = value(key)
                else:
                    self[key] = copy.deepcopy(value)

            return dict.__getitem__(self, key)

    return _DefMap(*args, **kwargs)