Python Monostate __new__ 的弃用警告 -- 能解释一下原因吗?

5 投票
2 回答
1287 浏览
提问于 2025-04-15 15:11

我在使用Python 2.6写了一个简单的Monostate。

class Borg(object):
    __shared_state = {}
    def __new__(cls, *args, **kwargs):
        self = object.__new__(cls, *args, **kwargs)
        self.__dict__ = cls.__shared_state
        return self

    def __init__(self, *args, **kwargs):
        noSend = kwargs.get("noSend", False)
        reportLevel = kwargs.get("reportLevel", 30)
        reportMethods = kwargs.get("reportMethods", "BaseReport")
        contacts= kwargs.get("contacts", None)

a = Borg(contacts="Foo", noSend="Bar", )

结果我收到了一个弃用警告。

untitled:4: DeprecationWarning: object.__new__() takes no parameters
  self = object.__new__(cls, *args, **kwargs)

经过一番搜索,我发现这个问题和Bug #1683368有关。但是我搞不懂这是什么意思。它在抱怨下面这一行

self = object.__new__(cls, *args, **kwargs)

看起来是没问题的。能不能用简单的语言解释一下为什么这是个问题?我明白“这和其他内置的东西,比如列表,不一致”,但我不太明白为什么。有没有人能告诉我正确的做法是什么?

谢谢

2 个回答

1

这个警告是因为 __new__() 方法可以接收参数,但这些参数在其他地方都被忽略了。所以,如果你在调用它的时候传入了参数(除了 cls 以外),就会出现这个警告。其实现在传入额外的参数并不会导致错误,只是这些参数没有任何作用。

在 Python 3 的版本中,传入这些参数就会变成错误了。

6

请查看 python-singleton-object-instantiation,并注意 Alex Martelli 的单例示例:

class Singleton(object):

    __instance = None

    def __new__(cls):
        if cls.__instance == None:
            __instance = type.__new__(cls)
            __instance.name = "The one"
        return __instance

关于 __new__ 的弃用 问题,Guido 给出了回答:

这条消息的意思就是字面上的意思。:-) 调用 object.__new__() 时,除了类参数之外没有必要传入其他参数,任何这样做的代码都是在把那些参数丢进了一个黑洞。

只有在 object.__new__() 没有被重写,而 __init__ 被重写 的时候,忽略额外参数才是有意义的——这时你有一个完全默认的 __new__,构造函数参数的检查就交给 __init__ 来处理。

这样做的目的是为了捕捉像 object(42) 这样的调用错误,这种调用传入了一个没有被使用的参数。这通常是你程序中的一个 bug 的表现。

--Guido

撰写回答