Предупреждения об устаревании Python с Monostate __new__ Может кто-нибудь объяснить, почему?

У меня есть базовый Monostate с Python 2.6.

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)

После небольшого поиска в Google я обнаружил, что это прикреплено к Bug # 1683368. Я не могу понять, что это значит. Он жалуется на следующую строку

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

Кажется, что все в порядке. Может ли кто-нибудь объяснить непрофессионалами, почему это проблема. Я понимаю, что «это несовместимо с другими встроенными функциями, например списком», но я не уверен, что понимаю, почему. Кто-нибудь объяснит мне, как это сделать?

Спасибо


person rh0dium    schedule 19.10.2009    source источник


Ответы (2)


См. python-singleton-object-instantiation и обратите внимание на Пример синглтона Алекса Мартелли:

class Singleton(object):

    __instance = None

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

На __new__ deprecation вопрос ответил Гвидо:

Сообщение означает именно то, что говорит. :-) Нет смысла вызывать object .__ new __ () с более чем параметром класса, и любой код, который это делал, просто сбрасывал эти аргументы в черную дыру.

Единственный раз, когда для object .__ new __ () имеет смысл игнорировать дополнительные аргументы, это когда он не переопределяется, но __init__ переопределяется - тогда у вас есть полностью заданный по умолчанию __new__ и проверка конструктора аргументы отнесены к __init__.

Цель всего этого - поймать ошибку в вызове, подобном объекту (42), который (снова) передает аргумент, который не используется. Часто это признак ошибки в вашей программе.

- Гвидо

person gimel    schedule 19.10.2009
comment
Это синглтон (он же горец) - это не борг (моногосударство). Я уже был [обучен] [1] этому. У меня также есть готовые комментарии Гвидо, но, как я сказал ранее, если ваш init имеет требования * args ** kwargs, тогда new также потребует их? Правильно?? [1]: stackoverflow.com/questions/1575680/ - person rh0dium; 19.10.2009
comment
Гвидо прямо говорит, что для проверки аргументов конструктора требуется только init. - person gimel; 20.10.2009

Предупреждение исходит из того факта, что __new__() может ИМЕТЬ аргументы, но поскольку они везде игнорируются, передача ему аргументов (кроме cls) вызывает предупреждение. На самом деле (в настоящее время) передача дополнительных аргументов не является ошибкой, но они не действуют.

В py3k передача аргументов станет ошибкой.

person Paul McMillan    schedule 19.10.2009
comment
Я не понимаю, как их игнорируют? Выньте * args и ** kwargs из new, и он взорвется, потому что они нужны init, который их ожидает. Последнее утверждение я пытаюсь предотвратить :-) Я хочу, чтобы оно работало в 3k. - person rh0dium; 19.10.2009
comment
Я не могу спорить с разработчиками языка. Если они говорят, что новое не требует аргументов, я заставляю его не принимать аргументов. __init__ и __new__ работают аналогичным образом, возможно, в вашем случае следует использовать init вместо new. - person Paul McMillan; 20.10.2009