1

此时我想创建一个具有两种方法的类(我也希望能够明显地改变类)。

class ogrGeo(object):

    def __init__(self):
        pass

    def CreateLine(self, o_file, xy):
        #lots of code


    def CreatePoint(self, o_file, xy):
        # lot's of the same code as CreateLine(), 
        # only minor differences

为了使事情保持清洁并尽可能少地重复代码,我正在寻求一些建议。这两种方法CreateLine()CreatePoint()共享很多代码。减少冗余:是否应该定义两种方法都可以调用的第三种方法?在这种情况下,您仍然可以单独调用 o = ogrGeo() o.CreateLine(...) o.CreatePoint(...)。还是应该将它们合并为一种方法?还有其他我没有想到或一无所知的解决方案吗?

已经感谢您的任何建议。

4

5 回答 5

3

是否应该将这些方法合并为一个是 API 设计的问题。如果这些功能有不同的目的,那么你将它们分开。如果客户端代码可能遵循该模式,我会合并它们

if some_condition:
    o.CreateLine(f, xy)
else:
    o.CreatePoint(f, xy)

但否则,不要合并。相反,将公用代码重构为私有方法,如果公用代码不涉及,甚至可以将其重构为独立函数self。Python 没有内置在语言中的“私有方法”的概念,但带有前导的名称_将被识别为这样。

于 2012-09-21T12:41:49.857 回答
2

将通用代码分解为(私有)辅助方法是完全正常的:

class ogrGeo(object)
    def __init__(self):
        pass

    def CreateLine(self, o_file, xy):
        #lots of code
        value = self._utility_method(xy)

    def CreatePoint(self, o_file, xy):
        # lot's of the same code as CreateLine(), 
        # only minor differences
        value = self._utility_method(xy)

    def _utility_method(self, xy):
        # Common code here
        return value

该方法可以返回一个值,也可以直接操作self.

一个忠告:阅读Python 风格指南并遵守它的约定。大多数其他 python 项目都这样做,如果你这样做,它将使其他 Python 开发人员更容易理解你的代码。

于 2012-09-21T12:42:51.797 回答
1

对于将重叠的代码片段,请考虑它们是否也可以是它们自己的单独函数。然后CreateLine将由对某些函数的几次调用组成,其中参数选择对 有意义CreateLine,同时CreatePoint将是几个函数调用,具有适当的参数以创建一个点。

即使这些新的辅助功能不会在其他地方使用,最好将它们模块化为单独的功能,而不是复制/粘贴代码。但是,如果创建这些结构所需的辅助函数非常具体,那么为什么不将它们分解为自己的类呢?

您可以创建一个“对象”类,其中包含创建对象的所有基础知识,然后具有派生自“对象”的“线”和“点”类。在这些类中,覆盖必要的函数,以便构造是特定的,依赖于基“对象”类中的辅助函数来处理重叠的代码部分。

然后ogrGeo该类将构造这些其他类的实例。即使“Line”或“Shape”的最终消费者不需要完整的类对象,您仍然可以使用这种设计,并赋予ogrGeo返回 Line 实例或 Point 实例的子片段的能力消费者确实希望使用。

于 2012-09-21T12:44:49.403 回答
1

这几乎无关紧要。您希望类方法尽可能地可用于调用程序,并且拥有两个方法比拥有一个带有要创建的对象类型的附加参数的单个方法更容易和更有效:

def CreateObj(self, obj, o_file, xy)    # obj = 0 for Point, 1 for Line, ...

建议:使用单独的 API 调用并将通用代码分解为可在您的类中调用的方法。

于 2012-09-21T12:46:24.110 回答
0

你也可以去另一个方向。特别是在以下情况下:

def methA/B(...):
    lots of common code
    small difference
    lots of common code

那么你可以做

def _common(..., callback):
    lots of common code
    callback()
    lots of common code
def methA(...):
    def _mypart(): do what A does
    _common(..., _mypart)
def methB(...):
    def _mypart(): do what B does
    _common(..., _mypart)
于 2012-09-21T13:05:04.410 回答