5

好的,这里是严肃的菜鸟问题,所以我正在寻找一个非常笼统的答案。我是 Python 新手,该语言看起来很简单,但是当我遇到问题时遇到了问题。来自静态类型语言,我的第一直觉是制作一些对象,这样我就可以传递相关数据的桶,同时保持我的逻辑简洁。

但这是 Python 中的事情吗?由于语言是动态类型的,所以让对象传递有什么意义吗?如果我可以即时设置字段,为什么还要提前定义字段?如果我没有字段,我为什么还要打扰一个对象呢?我不能用字典,它基本上是一样的吗?

所以我想我在问,如果我需要将我的数据访问代码与我的逻辑分开,属性桶是个好主意吗?还是人们不在 Python 中这样做而只使用字典?

编辑:

这是我要完成的工作的基本想法:

我有一个返回 json 字符串的 http api。我想用 urllib2 打那个 url,把它作为一个字符串带回来,然后使用 json.loads 把它变成一个 dict 对象。然后我想将mysql代码分成另一个类。显然我不想传递 20 个值,因为我已经有了一个包含所有值的 dict,那么创建一个动态对象并从 dict 添加每个值有什么好处?我仍然必须知道数据访问类中的所有名称,对吧?我不是真的在谈论性能,而是更多地谈论设计。

4

4 回答 4

4

在不知道您的具体要求的情况下,如果您想传递数据,我会说字典可能会更好。它们是内置的,它快速、简单并且每个程序员都能理解它们,这与开发人员必须查找特定属性的值对象之类的东西形成对比。

例子:

在这种情况下也相关:Jack Diederich 的停止写作课程(YT):

课程很棒,但也被过度使用了。本演讲将描述从现实世界代码中提取的类过度使用的示例,并从中重构出不必要的类、异常和模块。

于 2013-01-05T03:53:41.427 回答
2

对于只读数据,命名元组是一个不错的选择,您可以通过字段名称访问值,并且它比字典更节省内存。在我看来,传递的数据应该是只读的。

编辑:对于您的用例,我认为您应该将字典传递到管道中。创建一个仅用于数据存储的类并且不提供其他服务只会使代码更加复杂而没有什么好处。

于 2013-01-05T04:20:20.573 回答
0

你实际上发现了很多。如果代码是“严格的 Python”,人们往往不会制作 POPO 类型或 DTO 类型的对象。人们倾向于只传递他们需要的数据。但是,如果您正在与其他服务进行通信,则通信管道可能会生成您必须处理的较重类型的对象(例如,Suds 将服务中的数据类型非常接近地映射到 Python 对象)。

幸运的是(或不是),你可以两全其美。您可能会看到类似以下内容的“通用 DTO”(不一定是好的,但 pythonic):

   class Person:
     def __init__(self, *args, **kwargs):
       self.__dict__ = kwargs

因此,虽然它们没有设置surnamegivenName类型属性,但您可以添加它们只是为了它的语法糖。(如果你正在做一个列表理解很有用):

last_names = [x.surname for x in people]
于 2013-01-05T03:59:48.227 回答
0

除非我想要一个通用的键值数据类型,否则我不会使用字典,因为我不知道键是什么。对于在 C++ 或类似语言中使用对象的所有情况,您可以并且可能应该在 Python 中使用对象。

原因是尽管您可以使用 a dict,但它不提供封装或抽象。即使来自静态类型语言,您也应该了解这样做的好处。您无法dict验证其值。没有方便的地方记录 a 的结构dict或命名该结构。

有趣的是,Python 对象的属性一个字典。看一下这个:

>>> class Foo(object):
...   def __init__(self):
...     self.cat = 'meow'
...     self.dot = 'woof'
... 
>>> f = Foo()
>>> f.__dict__
{'dot': 'woof', 'cat': 'meow'}

而且,你可以让一个类看起来像dict

>>> class Animals(object):
...   def __getitem__(self, key):
...     if key == 'cat':
...       return 'meow'
...     if key == 'dog':
...       return 'woof'
...     raise KeyError(key)
... 
>>> a = Animals()
>>> a['cat']
'meow'
>>> a['dog']
'woof'
于 2013-01-05T04:00:09.253 回答