在完整的classmethod类

时间:2015-06-26 11:14:02

标签: python constructor class-method

假设我有以下课程:

class Context:

    element_list = []

    @classmethod
    def add(cls, element):
        cls.element_list.append(element)

    @classmethod
    def remove(cls, element):
        cls.element_list.remove(cls.element_list.index(element))

这个类接近Singleton类。目标是在我的程序中的任何位置更新element_list属性,而不传递Context实例作为我的函数的参数。

PyCharm告诉我应该定义一个__init__方法。但我不想创建这个类的两个不同的实例。我正在考虑创建一个这样的虚拟__init__方法:

def __init__(self):
    raise NotImplementedError("This class should not be initialized")

问题是(是):我应该定义一个__init__方法吗?如果有,怎么样?如果我使用单例类(参见:Is there a simple, elegant way to define singletons?

,而不是使用classmethod实现

1 个答案:

答案 0 :(得分:0)

  1. __init__方法不是强制性的。如果要将状态传递给正在初始化的实例,则应该只定义__init__方法。查看您提供的代码段,似乎并非如此。

  2. 在python中实现单例模式有几种方法(黑客):

    但是,我认为这些方法不是pythonic,大多数情况都应该避免使用。

    正如其他人所说,你总是可以使用python模块。 Python模块是Python编程语言最强大的功能之一。他们可以拥有状态(变量),行为(函数),并且在一个Python流程执行中,模块只会加载一次

    这意味着,在如下的目录结构中:

    .
    ├── bar.py
    ├── foo.py
    ├── main.py
    └── singleton.py
    

    你可以这样做:

    # file: singleton.py
    element_list = []
    

    从您的应用程序的其余部分,您只需导入并使用它:

    # file: foo.py
    import singleton
    
    def foo():
        # ... do complex computations ...
        singleton.element_list.append('baz')
    
    # file: bar.py
    import singleton
    
    def bar():
        # ... do more complex things ...
        if 'baz' in singleton.element_list:
            print('baz')
    
    # file: main.py
    import foo
    import bar
    
    foo.foo()
    bar.bar()
    # OUTPUTS: 'baz'
    

    正如您所看到的,除了简单和更优雅之外,使用该模块还可以为您提供所有常用的列表实用程序(例如,您可以singleton.element_list[1:]singleton.element_list + ['my', 'other', 'list'],依此类推)。如果您想按照自己的方式执行此操作,则必须实现其他类方法。