我经常需要创建一个结果对象实例来从函数返回复杂的值,并且想知道什么是好的 Pythonic 方法。
我知道密切相关的 attribute-assignment-to-built-in-object ,但它问他为什么需要破解子类变通方法才能使用“对象”。我明白为什么了。相反,我问的是标准库中是否存在现有支持,以避免通过现有类或函数使用“对象”和子类 hack。
实例化支持属性分配的实例的最简单、最Pythonic 的方法是什么?
我可以直接返回子类化“对象”答案。这真的没什么大不了的 - 只是想知道我是否错过了标准库或内置支持的更简洁的方法。
我正在尝试做的示例:
try:
returnval = object()
returnval.foo = 1
returnval.bar = 2
print "\n\nSuccess with %s" % (returnval), vars(returnval), "has __slots__:", hasattr(returnval, "__slots__"), "has __dict__:", hasattr(returnval, "__dict__")
except Exception, e:
print "\n\nFailure with %s:%s" % (returnval, e), "has __slots__:", hasattr(returnval, "__slots__"), "has __dict__:", hasattr(returnval, "__dict__")
如预期的那样失败了
Failure with <object object at 0x102c520a0>:'object' object has no attribute 'foo' has __slots__: False has __dict__: False
我并不惊讶。 'object' 是一个裸 stub ,并且不允许属性分配,因为它没有 __dict__。
相反,我必须声明一个占位符类。有更清洁的方法吗?
try:
class Dummy(object): pass
returnval = Dummy()
returnval.foo = 1
returnval.bar = 2
print "\n\nSuccess with %s" % (returnval), vars(returnval), "has __slots__:", hasattr(returnval, "__slots__"), "has __dict__:", hasattr(returnval, "__dict__")
except Exception, e:
print "\n\nFailure with %s:%s" % (returnval, e), "has __slots__:", hasattr(returnval, "__slots__"), "has __dict__:", hasattr(returnval, "__dict__")
这给出:
Success with <__main__.Dummy object at 0x102d5f810> {'foo': 1, 'bar': 2} has __slots__: False has __dict__: True
使用 Dummy/MyClass 方法可以避免这些问题,但它会散发出轻微的代码气味,使我的模块中充满 Dummy 类。
行不通/不令人满意的事情:
字典。如果我改用字典,我会避免这种情况,但我会失去简单的 returnval.foo 访问权限。
也许是 AttrDict 实现?但是那些来自第 3 方包,而不是标准库。
模拟。不是我想在这里使用的,因为这不是测试代码,我希望在 returnval.foo 不存在时抛出异常。
模块/类属性赋值。是的,我可以将属性分配给命名空间中的现有对象,例如类或模块声明。但这实际上是将属性分配给单例,并且连续的函数调用会相互破坏。
请您参考如下方法:
要么使用namedtuple或者坚持使用字典——如果你真的想要一个属性访问——create your own class for it :
>>> Dummy = namedtuple('Dummy', ['foo', 'bar'])
>>> d = Dummy(1, 2)
>>> d
Dummy(foo=1, bar=2)
>>> d.baz
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Dummy' object has no attribute 'baz'
