2012-09-21 65 views
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(...)。 或者我应该将它们合并成一种方法?还有没有想过或不知道的另一个解决方案?

感谢您的任何建议。

+0

感谢所有的建议家伙。最后,我将它作为一个具有两个公共方法和两个辅助函数的类来实现,以尽可能多地模块化代码。我对结果非常满意,特别是因为它的代码会使我的类的扩展非常简单(例如'create_polygon',...方法)。 – LarsVegas

回答

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 style guide并坚持它的约定。大多数其他的python项目都可以,如果你愿意的话,它会让你的代码更容易理解其他Python开发者。

+2

你提到我的方法名我想......真的。我的坏习惯。 – LarsVegas

3

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

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

但除此之外,不合并。相反,将公共代码重构为私有方法,或者如果通用代码不触及self,则甚至可以使用独立函数。 Python没有内置在该语言中的“私有方法”的概念,但具有前导_的名称将被识别为这样。

+0

如果我决定使用独立功能,继承如何?难道你不应该永远保持代码,以免你的课程导致? – LarsVegas

+0

@larsvegas:为什么?这意味着你永远不能在课堂外打电话。我倾向于将效用函数放在模块中而不是类中,但如果你不喜欢这样,你可以使用'staticmethod'。 Python不是Java :) –

+0

不,这不是我的意思。但如果你基于'ogrGeo'派生一个类,如果它是独立的,你将不会继承这个效用函数,对吗? – LarsVegas

1

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

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

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

然后ogrGeo类将构造这些其他类的实例。即使“线”或“形状”的最终消费者不需要完整的类对象,仍然可以使用此设计,并赋予ogrGeo返回线实例或Point实例的子部分的能力消费者确实希望使用。

1

这几乎没有关系。您希望类方法对于调用程序尽可能地可用,并且使用两种方法比使用附加参数创建对象类型的方法稍微简单和高效:

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

建议:使用单独的API调用,并将常用代码纳入可在类中调用的方法中。

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) 
相关问题