编码风格:创建支持属性分配的实例的轻量级/最简单的方法?

2024-10-01 04:55:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我经常需要创建一个result对象实例来从函数中返回复杂的值,并且想知道什么是一个好的Pythonic方法。你知道吗

我知道与之密切相关的attribute-assignment-to-built-in-object,但这是在问为什么他需要破解一个子类解决方法来使用“object”。我已经明白为什么了。我问的是,标准库中是否有现有的支持,以避免通过现有的类或函数使用“object”和子类hack。你知道吗

实例化一个支持属性分配的实例的最简单、最python的方法是什么?你知道吗

我可以直接回到子类化“object”答案。这真的没什么大不了的-只是想知道我是否错过了标准库或内置程序支持的更干净的方法。

我尝试做的示例:

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

我并不感到惊讶对象“”是空存根,不允许属性赋值,因为它没有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类。你知道吗

不起作用/不令人满意的事情:

字典。如果改用dict,我会避免这种情况,但我会失去简单的功能返回值foo进入。你知道吗

也许是AttrDict实现?但是这些都是第三方软件包,而不是标准的lib。你知道吗

嘲笑。不是我想在这里使用的,因为这不是测试代码,我希望在返回值foo不存在。你知道吗

模块/类属性分配。是的,我可以将属性分配给命名空间中的现有对象,比如类或模块声明。但这实际上是将属性分配给一个单例,连续的函数调用会互相碰撞。你知道吗


Tags: 对象实例方法标准属性objectfoowith
2条回答

轻量级的方法是使用函数作为容器

>>> foo = lambda: 0
>>> foo.bar = 'bar'
>>> foo.baz = 'baz'

如果您正在创建一组具有相同属性的不可变对象,collections.namedtuple可能更合适

>>> foo = namedtuple("foo", "bar, baz")
>>> Foo = foo('bar', 'baz')
>>> foo.bar
'bar'
>>> foo.baz
'baz'

要么使用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'

相关问题 更多 >