我经常会写一个类,以及与该类紧密相连的辅助函数。对于我当前的一个Window
类来包装一些win32api
调用,以及查找窗口的函数。这些辅助函数应该是给定模块中的全局变量,还是它们应该是Window
类的类方法。也就是说,我应该在我的模块中:
class Window(object):
def __init__(self, handle):
self.handle = handle
...
...
@classmethod
def find_windows(cls, params):
handles = ...
return map(cls, handles)
用法为:
from window import Window
windows = Window.find_windows("Specialty")
或者我应该这样做:
class Window(object):
def __init__(self, handle):
self.handle = handle
...
...
def find_windows(params):
handles = ...
return map(Window, handles)
用法为:
from window import Window, find_windows
windows = find_windows("Speciality")
更简洁地说:分组应该在类级别(例如,它们是Java中的静态方法)还是模块级别?
答案 0 :(得分:2)
第一种方法的优点是,如果你继承Window
,你可以覆盖你的find_windows
方法(与java中的静态方法不同)。但是,如果覆盖最终会有意义,这只会有用,否则我认为将其作为一个函数看起来更好。
编辑:如果您有多种方法可以找到Window对象,那么有一个名为WindowFinder或WindowManager的附加类可以封装查询/查找逻辑。
这是django中使用的模式,如果你的Window类让我们说一个db模型,那么你的Window.objects指向一个WindowManager。窗口管理器具有构建SQL查询的方法。
然后,您可以执行以下操作:
Window.objects.all()
或
Window.objects.filter(name="Speciality")
答案 1 :(得分:2)
如果find_windows()
不需要访问或了解Window
类的内部工作原理,我会将其作为全局函数。通过增加不同代码片段之间的依赖关系几乎无法获得,特别是当它基本上只是源所在位置的问题时。
答案 2 :(得分:0)
如果我理解正确,您的find_windows
函数会从句柄列表中创建Window
个实例列表。
它表现为构造函数,因此,我会使它成为函数,而不是classmethod
类的Window
。正如我在评论中提到的那样,感觉更自然,但这只是一种预感。
修改强>
@Ioan Alexandru Cucu的回答让我思考你将Window
子类化为SubWindow
的情况。
如果find_windows
(或建议的create_windows
)是classmethod
,它将返回SubWindow
个实例的列表,而如果它只返回Window
个实例是我建议的独立功能。
这可以被认为是一个有趣的功能,因此将find_windows
保持为classmethod
是有意义的。我仍然会在文档字符串或其他地方提出一些解释理由的评论。
<tl;dr>
:依赖。