1

我正在以这种方式实现复合模式:

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

但在我的叶子中,我不能要求:

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

没有引发异常。

我必须忽略 pylint 警告还是编码错误?

4

5 回答 5

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)
于 2009-07-07T09:52:05.310 回答
2

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

于 2010-02-26T13:21:51.433 回答
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,一切都会好起来的!

于 2009-07-07T10:22:43.533 回答
1

这样的编码还不错,但是__init__根本不需要组件的。如果你想要它,你可以忽略 pylint,但最好__init__从 Component.xml 中删除它。

拥抱动态!

于 2009-07-07T10:21:46.920 回答
1

您要保证基类 Component 未实例化。这是其他编程语言(如 C++)中常见的一种高贵的客套话(您可以将构造函数设为私有,以防止直接使用)。

但它在 Python 中不受支持。Python 不支持所有编程概念,而且更“动态”。因此,初始化是以“Pythonic”方式完成的,因此不支持您的概念。

与其他语言相比,Python 更多地基于信任——因此,例如,不支持静态变量,私有变量也仅以有限的方式。

你可以做什么(当你不信任你的模块的用户时)——你可以通过将基类命名为“_Component”来隐藏它——让它成为内部机密。但这当然会造成其他麻烦。

于 2009-07-07T10:07:28.633 回答