问题 在python中组织类和模块


我试图弄清楚如何组织模块和类,我有点头疼。来自C ++,我习惯于封装处理该数据所需的所有数据和方法的类。在python中有模块然而从我看过的代码中,有些人有很多 疏松 函数存储在模块中,而其他函数几乎总是将它们的函数绑定到类作为方法。

例如,假设我有一个数据结构,并希望将其写入磁盘。

一种方法是为该对象实现一个save方法,以便我可以输入

MyObject.save(filename)

或类似的东西。我所看到的同等比例的另一种方法是拥有类似的东西

from myutils import readwrite

readwrite.save(MyObject,filename)

这是一个小例子,我不确定这个问题究竟是如何具体的python,但我的一般问题是在函数与方法组织方面最好的pythonic实践是什么?


10488
2017-08-16 23:23


起源



答案:


好像松散的功能打扰你。这是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 到每个方法参数列表。

我尝试编写尽可能多的模块级函数。如果某个函数只能用于特定类的实例,我会在类上创建一个方法。否则,我尝试使它适用于模块中定义的每个类的实例,它们是有意义的。

您给出的确切示例背后的理性是,如果每个类都有一个save方法,那么如果您以后更改了保存数据的方式(从文件系统到数据库或远程XML文件),那么您必须更改每个类。如果每个类实现一个接口来产生它想要保存的数据,那么你可以编写一个函数来保存每个类的实例,并且只改变一次该函数。这被称为单一责任原则:每个类应该只有一个改变的理由。


13
2017-08-16 23:46





如果你想要保存到磁盘的常规旧类,我只是将它作为实例方法。如果它是一个可以处理不同类型对象的序列化库,我会采取第二种方式。


3
2017-08-16 23:26



术语“类方法”听起来像一个 classmethod,这是不适用的。适当的东西将被称为“方法”或“实例方法”。 - Mike Graham
你是对的。我的意思是实例方法。 - Matt Williamson


答案:


好像松散的功能打扰你。这是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 到每个方法参数列表。

我尝试编写尽可能多的模块级函数。如果某个函数只能用于特定类的实例,我会在类上创建一个方法。否则,我尝试使它适用于模块中定义的每个类的实例,它们是有意义的。

您给出的确切示例背后的理性是,如果每个类都有一个save方法,那么如果您以后更改了保存数据的方式(从文件系统到数据库或远程XML文件),那么您必须更改每个类。如果每个类实现一个接口来产生它想要保存的数据,那么你可以编写一个函数来保存每个类的实例,并且只改变一次该函数。这被称为单一责任原则:每个类应该只有一个改变的理由。


13
2017-08-16 23:46





如果你想要保存到磁盘的常规旧类,我只是将它作为实例方法。如果它是一个可以处理不同类型对象的序列化库,我会采取第二种方式。


3
2017-08-16 23:26



术语“类方法”听起来像一个 classmethod,这是不适用的。适当的东西将被称为“方法”或“实例方法”。 - Mike Graham
你是对的。我的意思是实例方法。 - Matt Williamson