Синтаксис Python Singletons и почему он выглядит так? - PullRequest
1 голос
/ 05 марта 2011

мой первый вопрос здесь:

Я искал в Интернете, а также прочитал несколько вопросов и ответов здесь и наконец выяснил, как написать синглтон-классы для моих кодов Python. Я также прочитал документацию по Python о функции new () и некоторых других вещах, но все еще не понял, как и что означает все это new (cls, * args, *). * KW) вещи и т. д.

например, я написал такой тестовый код:

class Singleton(object):

    def __new__(cls, *args, **kwargs):
        if '_inst' not in vars(cls):
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        return cls._instance

class printer(Singleton):

    def __init__(self):

        print "I am a new Object, and will remain until the end of time!"

if __name__ == '__main__':
    printer()

и в результате получается текст «Я новый объект и останусь до конца времени!» Но как это работает, я имею в виду, я не знаю, как сказать, например, я действительно смущен:

переменные (кл.): В строке if '_inst' not in vars(cls)

откуда выходят переменные (cls), я не заявлял об этом раньше! Может кто-нибудь, пожалуйста, проясните это для меня в классе синглтонов, а также немного о последней строке

if __name__ == '__main__':
    printer()

Ответы [ 3 ]

2 голосов
/ 05 марта 2011

Прежде всего, это неправильно:

class Singleton(object):
    def __new__(cls, *args, **kwargs):
        if '_inst' not in vars(cls): # <-- this must of course also be "_instance"
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        return cls._instance

Явный метод __new__ можно использовать как фабричный шаблон, поэтому, когда вы пишете printer(), Python сначала вызовет __new__, передавая тип класса и параметры конструктора (в этом примера нет).

'_instance' not in vars(cls) просто означает поиск того, имеет ли класс атрибут «_instance» (то есть синглтон). Если нет, то один создан. Трюк с vars (встроенная функция, чтобы ответить на ваш вопрос) не нужен, можно также использовать cls._instance и ловить AttributeError, например.

И последнее:

if __name__ == '__main__':
    printer()

Это просто создает экземпляр printer (с использованием Singleton.__new__), если скрипт выполняется непосредственно (т.е. если __name__ == '__main__', а не при импорте модуля).

2 голосов
/ 05 марта 2011

Вместо использования Singleton, вы рассматривали возможность использования Borg?

Идея в том, что Python хранит все состояние для экземпляров в атрибуте (__dict__), если вы просто переназначаете этот атрибут на атрибут класса, то вы можете создавать экземпляр класса столько раз, сколько захотите, но все они будут иметь одинаковое состояние.

2 голосов
/ 05 марта 2011

Вы должны использовать модули как синглтоны в python, потому что они ведут себя точно так же, как один.

Вот еще один вопрос: Существует ли простой, элегантный способ определения синглетонов?

...