python - 在 Python 中优先使用字典而不是对象

标签 python design-patterns object dictionary

当您所做的只是描述某物的属性时,在 Python 中使用字典而不是对象是否有好处(反之亦然)?

我目前正在从事的项目有很多地方使用了字典,而这些地方我通常会创建对象。在我看来,对象提供了更多的结构,并允许通过 pylint 等程序更好地检查程序员的错误,但是很难解释为什么我会使用对象而不是字典。

举个模拟的例子,一个模块创建 Widgets 并包含这样的方法:

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,这可以通过将 Widget 分解为更小的组件/相关部分并创建更多对象等来避免,但我觉得这是一个很好的“第一步”。这有任何意义吗?

字典的好处:

  1. 更快和/或更高效的内存

字典的缺点:

  1. 无法使用静态代码检查器捕获一些错误
  2. 所有小部件属性的完整列表可能永远不会出现或为人所知

对象的好处:

  1. 准确了解“Widget”由什么组成
  2. 可能使用静态代码检查器捕获错误(尽管使用 ** 魔法可以防止其中的一些错误)

对象缺点:

  1. 速度较慢和/或内存效率较低

这似乎是一个愚蠢的问题,但是为什么要用对象来做一些可以用字典来做的事情呢?

最佳答案

不,使用字典而不是对象没有任何好处 - 对象中的数据通常存储在字典中。

使用对象而不是字典可能会有好处。看: http://docs.python.org/reference/datamodel.html#slots

关于python - 在 Python 中优先使用字典而不是对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7224510/

相关文章:

Python CGI 脚本 IOError Broken Pipe

design-patterns - IntelliJ 中的构建器模式代码生成

php - 将 stdObject 转换为数组 - 调用函数

javascript - 在javascript中按对象内的数字/id排序

Python AES 256 CBC 加密 - ValueError : Incorrect AES key length

python - 如何定义具有动态输入的 python 字符串(准)常量?

python - Sklearn 列转换器 ValueError : could not convert string to float:

asp.net-mvc - 上帝 Controller - 如何防止它们?

xcode - 代码模式 : Loading TabBarController objects directly from independent . xib 文件(而不是来自 MainWindow.xib)

javascript - 数组值的更改更改此数组的前一个克隆