python - Python 如何提供一种可维护的方式来在系统中传递数据结构?

标签 python

一般来说,我是动态语言的新手,我发现像 Python 这样的语言更喜欢简单的数据结构,比如字典,用于在系统的各个部分之间(跨函数、模块等)发送数据。

在 C# 世界中,当系统的两个部分进行通信时,开发人员会定义一个类(可能是实现接口(interface)的类),该类包含属性(例如具有姓名、出生日期等的 Person 类),其中发送方系统实例化类并为属性分配值。接收方然后访问这些属性。该类称为 DTO,它“定义明确”且明确。如果我从 DTO 的类中删除一个属性,编译器将立即警告我所有使用该 DTO 的代码部分并试图访问现在不存在的属性。我确切地知道我的代码库中出现了什么问题。

在 Python 中,生成数据(发送方)的函数通过构建字典并返回它们来创建隐式 DTO。来自一个编译的世界,这让我害怕。我立即想到了一个大型代码库的场景,其中一个生成字典的函数更改了一个键的名称(或者一个键被完全删除)并且大量潜在的 KeyErrors 开始作为代码库的片段出现使用该字典并期望 key 不再能够访问他们期望的数据。如果没有单元测试,开发人员将无法可靠地知道这些错误将出现在何处。

也许我完全误解了。字典是传递数据的最佳实践工具吗?如果是这样,开发人员如何解决此类问题?如何维护隐式数据结构和使用它们的函数?我如何减少对看似巨大的不确定性的恐惧?

最佳答案

Coming from a compiled world, this scares me. I immediately think of the scenario of a large code base where a function producing a dictionary has the name of a key changed (or a key is removed altogether) and boom- tons of potential KeyErrors begin to crop up as pieces of the code base that work with that dictionary and expect a key are no longer able to access the data they were expecting.

我只想强调你问题的这一部分,因为我觉得这是你试图理解的重点。

Python 的开发理念有点不同;因为对象可以在不抛出错误的情况下发生变化(例如,您可以向实例添加属性而无需在类中声明它们),Python 中的常见编程实践是 EAFP :

EAFP

Easier to ask for forgiveness than permission. This common Python coding style assumes the existence of valid keys or attributes and catches exceptions if the assumption proves false. This clean and fast style is characterized by the presence of many try and except statements. The technique contrasts with the LBYL style common to many other languages such as C.

上面引用的 LBYL 是“三思而后行”:

LBYL

Look before you leap. This coding style explicitly tests for pre-conditions before making calls or lookups. This style contrasts with the EAFP approach and is characterized by the presence of many if statements.

In a multi-threaded environment, the LBYL approach can risk introducing a race condition between “the looking” and “the leaping”. For example, the code, if key in mapping: return mapping[key] can fail if another thread removes key from mapping after the test, but before the lookup. This issue can be solved with locks or by using the EAFP approach.

所以我想说这有点正常,在 Python 中,您期望对象会表现良好并优雅地处理自己(主要是通过抛出大量异常)。传统的“对象隐藏”和“接口(interface)契约”并不是 Python 的全部。就像学习其他任何东西一样,您必须适应编程环境及其规则。

你问题的另一部分:

Are dictionaries a best practice tool for passing data around? If so, how do developers solve this kind of problem?

这里的答案取决于您的问题领域。如果您的问题域不适合自定义对象,那么您可以传递任何类型的容器(列表、元组、字典)。然而,如果您必须传递装饰数据(“丰富的”数据)的只是对象,那么您的代码中会充斥着不定义行为而是定义事物属性的类。

哦,顺便说一下 - 这个获取键和引发 KeyError 的问题已经解决了,因为 Python 字典有一个 get 方法,它可以返回一个默认值(它默认返回哨兵 None 对象)当键不存在时:

>>> d = {'a': 'b'}
>>> d['b']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'b'
>>> d.get('b')  # None is returned, which is the only
                # object that is not printed by the
                # Python interactive interpreter.
>>> d.get('b','default')
'default'

关于python - Python 如何提供一种可维护的方式来在系统中传递数据结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22370488/

相关文章:

python - wx.Grid 和 wx.StockCursor

python - 如何删除列中的特殊字符并将列转换为 float ?

python - 分组依据和计数值

python - Valign 不在 kivy 工作?

python - GridSearchCV(sklearn) 中的多个估计器

python - PySpark distinct().count() 在 csv 文件上

python - Pyinstaller 创建空 Dist 文件夹

python - 个人资料图片或头像的电子邮件标题?

python - Django - 使用相关模型字段的性能

python - 我如何告诉 django-admin 使用哪个设置模块?