【问题标题】:Implementing Singleton pattern results in TypeError: unbound method foobar() must be called with Singleton instance as first argument实现单例模式导致类型错误:必须以单例实例作为第一个参数调用未绑定的方法 foobar()
【发布时间】:2015-07-30 13:47:00
【问题描述】:

我正在尝试在 Python (2.7) 中实现 Singleton pattern

我已经阅读了有关实现的严重帖子(1234),我想编写自己的版本。 (我理解的版本。我是 Python 新手。)

所以我正在使用一种方法创建单例,该方法将创建我的单个对象本身,该对象将在每次 Singleton.Instance() 调用时返回。

但是错误信息总是一样的:

Traceback (most recent call last):
  File "./test4.py", line 24, in <module>
    print id(s.Instance())
  File "./test4.py", line 15, in Instance
    Singleton._instance = Singleton._creator();
TypeError: unbound method foobar() must be called with Singleton instance as first argument (got nothing instead)

我在这里滚动:

class Singleton(object):

    _creator = None
    _instance = None

    def __init__(self, creator):
        if Singleton._creator is None and creator is not None:
            Singleton._creator = creator

    def Instance(self):

        if Singleton._instance is not None:
            return Singleton._instance

        Singleton._instance = Singleton._creator();

        return Singleton._instance;

def foobar():
    return "foobar"

s = Singleton( foobar )

print id(s.Instance())

这是为什么呢?更具体地说:如何在 Python 中调用存储在类变量中的 def 方法?

【问题讨论】:

  • 我建议使用可以应用于任何类的装饰器(例如定义自己的@singleton
  • 装饰器非常适合用于生产代码,但对于刚刚编写“我理解的版本。我是 Python 新手”的人来说,最初的代码尝试可能不是那么好。

标签: python python-2.7 design-patterns singleton


【解决方案1】:

问题是当你将它插入到类中时,Python 会自动为你提供一个方法。您需要将其设为静态方法以避免这种情况。

class Singleton(object):

    _creator = None
    _instance = None

    def __init__(self, creator):
        if Singleton._creator is None and creator is not None:
            Singleton._creator = staticmethod(creator)

    def Instance(self):

        if Singleton._instance is not None:
            return Singleton._instance

        Singleton._instance = Singleton._creator();

        return Singleton._instance;

def foobar():
    return "foobar"

s = Singleton( foobar )

print id(s.Instance())

【讨论】:

  • 我不是这个意思。单例本身可以被创建多次。重要的是creator 只会被调用一次并返回多次。
  • @ewasser -- 啊,我明白了,我看到了问题并编辑了答案。
  • 谢谢。构造的staticmethod() 是什么?难道也是装饰师?
  • 是的,它也可以用作装饰器。通常,当您将函数绑定到类时,解释器假定它应该将函数包装在实例方法中——这将确保传递的第一件事是类的实例。但它只对还不是实例、类或静态方法的函数执行此操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-10
  • 1970-01-01
  • 2017-04-03
  • 2013-12-31
  • 2014-12-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多