我可以添加属性的最常见的Python类型是什么?

7
我有一个名为Foo的类,其中包含一个名为isValid的方法。然后我有一个名为bar()的方法,它接收一个Foo对象,并且其行为取决于该对象是否有效。
为了测试这个功能,我想传递一个对象到bar()方法中,使其isValid方法始终返回False。由于某些原因,在测试时我不能创建一个Foo对象,因此我需要一个虚拟对象来代替它。我最初想到的是创建一个最通用的对象并向其中添加isValid属性,以便将其用作Foo。但那并不完全行得通:
>>> foo = object()
>>> foo.isValid = lambda : False
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'isValid'

我发现对象没有__dict__,因此您不能向其添加属性。此时,我使用的解决方法是临时创建一个类型,然后创建该类型的对象:

>>> tmptype = type('tmptype', (), {'isValid' : lambda self : False})
>>> x = tmptype()
>>> x.isValid()
False

但这似乎太过牵强。一定有一些常见的类型可供我用于此目的,但是哪种类型呢?

3个回答

7

你的想法是对的,但可以更通用。要么

 tmptype = type('tmptype', (object,) {})

或者

 class tmptype(object):
     pass

然后你可以直接执行以下操作:
foo = tmptype()
foo.is_valid = lambda: False

就像您想要使用object一样。这样,您可以为所有动态的、猴子补丁需求使用相同的类。


嗯,基本上就是相同的东西分布在更多的行中,并使用新的样式类。但我的问题仍然存在:难道没有一些通用的可用类型来实现相同的目的吗?像带有__dict__的对象之类的东西?我真的需要为此创建一个类型吗? - ricab
@ricab:这是我从谷歌上找到的一个拒绝想法的链接。你可能会找到其他的。http://mail.python.org/pipermail/python-bugs-list/2007-January/036866.html - aaronasterling
哦,好的,所以没有这样的类型。我以为我可能只是没找到它...谢谢 - ricab
上面的 type 命令可能有一个打字错误,因为我得到了 "SyntaxError: invalid syntax" 的语法错误;似乎需要另一个逗号,所以 tmptype = type('tmptype', (object,), {}) 对我来说可以正常工作。 - sdaau

4

1

因为我不想用额外的类来分散读者的注意力,这些类的使用可能会让他感到困惑,还需要去寻找。此外,这种方式可以使类型的定义仅在创建其唯一对象的地方,以便立即找到单一目的。定义是在使用它的地方,这使得测试是自包含的。当您看到对象时,您会看到类型定义,当您看到类型定义时,您知道它的唯一目的。无需查找其他地方,即可清楚地了解对象和类型的目的。 - ricab
顺便说一下,我读了这篇文章,但我不明白为什么在这种情况下使用lambda表达式不好... - ricab
我知道它是为了一个单一的目的等等...但这不是正确的方法,在我看来... 我可以写 try: a.next() except StopIterationError: pass 代替 for x in a: #pass 但这不是正确的方法...我知道在某些情况下你可以使用它,但为什么要这样做呢? 在我看来...这篇文章是关于lambda的用法,它写道lambda不应该被用来代替普通的'def',而只有当Python需要表达式而不是语句时才能使用...所以,你可以这样做,但我认为这不是解决问题的正确方法... - Ant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接