我在试图找出如何组织模块和类的过程中遇到了一些麻烦。来自C ++,我习惯于封装处理该数据所需的所有数据和方法的类。在python中有一些模块,但是从我看过的代码中,有些人有很多松散的函数存储在模块中,而其他人几乎总是将它们的函数绑定到类作为方法。
例如,假设我有一个数据结构,并希望将其写入磁盘。
一种方法是为该对象实现一个save方法,这样我就可以输入
MyObject.save(filename)
或类似的东西。我所看到的另一种方法是等同于
from myutils import readwrite
readwrite.save(MyObject,filename)
这是一个小例子,我不确定python是如何解决这个问题的,但我的一般问题是在函数与方法组织方面最好的pythonic实践是什么?
答案 0 :(得分:13)
似乎松散的功能打扰了你。这是python的方式。这是有道理的,因为python中的模块实际上只是与任何其他对象在同一基础上的对象。它确实具有语言级支持,可以从文件中加载它,但除此之外,它只是一个对象。
所以,如果我有一个模块foo.py
:
import pprint
def show(obj):
pprint(obj)
然后我从bar.py
import foo
class fubar(object):
#code
def method(self, obj):
#more stuff
foo.show(obj)
我实际上是访问foo
对象上的方法。 foo
模块的数据属性只是foo
中定义的全局变量。模块是单例的语言级实现,无需在每个方法参数列表中添加self
。
我尝试编写尽可能多的模块级函数。如果某个函数只能用于特定类的实例,我会在类上创建一个方法。否则,我尝试使它适用于模块中定义的每个类的实例。
您给出的确切示例背后的理性是,如果每个类都有一个保存方法,那么如果您以后更改保存数据的方式(从文件系统到数据库或远程XML文件),那么您必须更改每个类。如果每个类实现一个接口来产生它想要保存的数据,那么你可以编写一个函数来保存每个类的实例,并且只更改一次该函数。这被称为单一责任原则:每个班级应该只有一个改变的理由。
答案 1 :(得分:3)
如果您想要保存到磁盘的常规旧类,我只会将其作为实例方法。如果它是一个可以处理不同类型对象的序列化库,我会采取第二种方式。