【发布时间】:2011-08-28 22:49:43
【问题描述】:
当您所做的只是描述某物的属性时,在 Python 中使用字典而不是对象有什么好处(反之亦然)?
我目前正在从事的项目有很多地方使用字典,而我通常会在这些地方创建对象。在我看来,对象提供了更多的结构,并允许通过 pylint 等程序更好地检查程序员的错误,但很难解释为什么我会使用对象而不是 dict。
对于一个模拟示例,一个模块创建小部件并包含如下方法:
def create(self, propertyA, propertyB=55, propertyC="default",
propertyD=None, propertyE=None, propertyF=None, propertyG=None,
propertyH=None, propertyI=None):
该方法将通过创建一个字典并将其传递给它来调用,就像这样:
widget_client = WidgetClient()
widget = {
"propertyA": "my_widget",
"propertyB": 10,
...
}
widget_client.create(**widget)
当我看到这个时,我发现这些属性中的每一个都描述了一个“小部件”,并且想要执行以下操作:
class Widget(object):
"""Represents a widget."""
def __init__(self, propertyA, **kwargs):
"""Initialize a Widget.
:param propertyA: The name of the widget.
:param kwargs: Additional properties may be specified (see below).
:returns: None
"""
self.propertyA = propertyA
self.propertyB = kwargs.get("propertyB", 55)
self.propertyC = kwargs.get("propertyC", "default")
self.propertyD = kwargs.get("propertyD", None)
self.propertyE = kwargs.get("propertyE", None)
self.propertyF = kwargs.get("propertyF", None)
然后将 create() 方法更新为如下所示:
def create(self, widget):
最终会这样调用:
widget_client = WidgetClient()
widget = Widget(propertyA="my_widget")
widget.propertyB = 10
...
widget_client.create(widget)
在我看来,这显然更好,但我过去犯过错,我想不出如何解释自己。当然,我仍在使用 **kwargs,这可以通过将小部件分解成更小的组件/相关部分并创建更多对象等来避免,但我觉得这是一个很好的“第一步”。这有任何意义吗?
字典的好处:
- 更快和/或更节省内存
字典的缺点:
- 无法使用静态代码检查器捕获某些错误
- 所有小部件属性的完整列表可能永远不会出现或不为人所知
对象的好处:
- 确切了解“小部件”的组成部分
- 可能会使用静态代码检查器捕获错误(尽管使用 ** 魔法可以防止其中一些错误)
对象缺点:
- 速度较慢和/或内存效率较低
这似乎是一个愚蠢的问题,但为什么要对可以用字典完成的对象做一些事情呢?
【问题讨论】:
-
你考虑过namedtuple吗?
-
Do I need to learn about objects, or can I save time and just learn dictionaries? 和其他人的部分副本。只需搜索标记为
[python]和[oop]的问题。 -
也许你应该切换到 Javascript,其中对象是字典,这样整个问题就消失了 :-)
-
另外,“对象”在这里并不正确(正如我对链接问题的回答所解释的那样)你真的是指用户定义的类。
-
“更快和/或更高的内存效率”和“更慢和/或更低的内存效率”是不合常理的谈话。如果你需要关心这些,你不应该使用 Python。所以现在你只剩下字典的缺点和对象的好处了。 pythonic的选择现在应该很明显了
标签: python design-patterns object dictionary