Python复合模式异常处理& pylint的

时间:2009-07-07 09:42:32

标签: python composite pylint

我在this way中实现了一个复合模式:

1)“抽象”组件是:

class Component(object):
    """Basic Component Abstraction"""
    def __init__(self, *args, **kw):
        raise NotImplementedError("must be subclassed")

    def status(self):
        """Base Abstract method"""
        raise NotImplementedError("must be implemented")

2)一片叶子:

class Leaf(Component):
    """Basic atomic component
    """
    def __init__(self, *args, **kw):
        self.dict = {}

    def status(self):
        """Retrieves properties
        """
        return self.dict

问题是pylint当然会产生这个警告:

Leaf.__init__: __init__ method from base class 'Component' is not called

但是在我的Leaf中我不能要求:

def __init__(self, *args, **kw):
    Component.__init__(self, *args, **kw)
    self.dict = {}

没有提出异常。

我必须忽略pylint警告或编码错误吗?

5 个答案:

答案 0 :(得分:4)

抽象初始化器是个坏主意。您的代码可能会发展,以便您希望在根组件中进行一些初始化。即使你没有为什么要求执行初始化程序。对于某些子类,空的初始值设定项是可接受的选择。

如果您不想要任何Component类的实例,请在初始化程序中检查它:

class Component(object):
    def __init__(self, **kwargs):
        assert type(self) != Component, "Component must not be instantiated directly"

class Leaf(Component):
    def __init__(self, some, args, **kwargs):
        # regular initialization
        Component.__init__(self, **kwargs)

答案 1 :(得分:2)

补充马库斯思想的另一个建议:

如果你真的必须,我建议你使用__new __并检查给定的对象类型。当它是“组件”时,您可以触发您的例外:

class Component(object):
"""Basic Component Abstraction"""

def __new__(objType, *args, **kwargs):
    if objType == Component:
       raise NotImplementedError("must be subclassed")
    return object.__new__(type, *args, **kwargs)

创建子类时,objType将是!= Component,一切都会好的!

答案 2 :(得分:2)

将您的类Component重命名为AbstractComponent应该有所帮助。如果不应该由子类调用,则不要在基类中提供__init__方法。

答案 3 :(得分:1)

您希望保证基类Component不是实例化的。这是一个在C ++等其他编程语言中很常见的高级客户(你可以将构造函数设置为私有,以防止直接使用)。

但Python不支持它。 Python不支持所有编程概念,也更“动态”。所以初始化是以“Pythonic”方式完成的,因此不支持你的想法。

Python比其他语言更基于信任 - 因此,例如静态变量不受支持,私有变量也只是以有限的方式。

你可以做什么(当你不信任模块的用户时) - 你可以通过命名它来“隐藏基类” - “_Component” - 使它成为一个内部秘密。但当然这可能会带来其他麻烦。

答案 4 :(得分:1)

这样编码也不错,但根本不需要组件的__init__。如果您需要,可以忽略pylint,但最好只从组件中删除__init__

拥抱动力!