我正在嘲笑一些数据,我需要能够通过点语法访问属性,以便保持运行时代码的顺序。当我尝试执行以下操作时,出现错误:
mockdata = object()
mockdata.name = "Hello"
object_under_test.evaluate(mockdata)
如何编写Python代码,使我能够设置这样的属性而无需创建类?
答案 0 :(得分:6)
创建可以接受属性分配的 object 变体:
>>> class Object(object):
pass
>>> mockdata = Object()
>>> mockdata.someattr = somevalue
答案 1 :(得分:2)
如果您不想“创建一个类”(我将使用class
关键字来定义一个类),您可以这样做:
mockdata = type("Mockdata", (object,), {})()
这仍然会创建一个类(object
的子类),但它在实例化之前没有为它指定一个名称,我想你可能会觉得它更适合这种一次性使用,因为它没有不要弄乱你的名字空间。
答案 2 :(得分:1)
是的,正如Raymond Hettinger所说,只需创建类可以保存属性,但是大多数情况下,当您进行模拟时,您可能需要设置一些返回值来验证某些方法,并且您可以像通常那样执行此操作任何课程。如果你想在某个可用类中模拟一个方法,那么有些库可以帮助你做到这一点,其中一个被称为Mock。
答案 3 :(得分:1)
其他想法,按顺序递减(IMO)。
我建议这样做的原因是你通常想要模拟这样的对象用于测试目的。如果是这样,您希望确保.evaluate
向mockdata
做正确的事情:调用正确的方法,访问正确的属性等等。模拟库允许您在测试框架内模拟对象,所以你不必手动检查所有这些。
使用dict
- 将字符串映射到值的常用方法:
mockdata = {}
mockdata["name"] = "Hello"
object_under_test.evaluate(mockdata)
如果您知道自己想要的字段,请使用NamedTuple
:
import collections
MockData = collections.namedtuple('MockData', ('name', 'value', ...))
mockdata = MockData(name="Hello", value=None, ...)
object_under_test.evaluate(mockdata)
使用任何旧对象。 lambda: None
class Object(object): pass
将会有效。
如果你是邪恶的,请使用attrdict。 (注意:实际上并没有这样做。但你可能会发现它很酷。)
class attrdict(dict):
def __init__(self, *args, **kwargs):
dict.__init__(self, *args, **kwargs)
self.__dict__ = self
mockdata = attrdict()
mockdata["name"] = "Hello"
object_under_test.evaluate(mockdata)
顺便说一句,你可能想知道为什么object().name = "Hello"
不起作用。这是因为object()
是一个奇怪的野兽,你可能不想使用它。正如docs所说:
注意:
object
没有__dict__
,因此您无法将任意属性分配给object
类的实例。