Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 13, 2017 11:34:20

sys_dev
От:
Зарегистрирован: 2011-06-22
Сообщения: 26
Репутация: +  0  -
Профиль   Отправить e-mail  

Как реализовать singleton?

У меня есть объект webdriver.Chrome и мне нужно его использовать в 3 классах в одном модулей. Передвать объект драйвера из класса в класс не хочется и напрашивается решение с реализацией синглтона.

Каким я вижу использование этого синглтона?

 class WebDriver:
   __driver = webdriver.Chrome
   pass
driver = WebDriver.instance
driver.get('python.su')
page = driver.page_source()

Другими словами мой WebDriver должен повторять интерфейс webdriver.Chrome , возможно перенаправляя в __driver.

Как это сделать на Python?



Офлайн

#2 Янв. 13, 2017 12:49:27

4kpt_IV
Зарегистрирован: 2016-01-08
Сообщения: 999
Репутация: +  49  -
Профиль   Отправить e-mail  

Как реализовать singleton?

Синглетон - это антипаттерн. Не надо его делать
Ну а если все же надо, тогда пользуемся __getattr__, __setattr__ и их товарищам.

Офлайн

#3 Янв. 13, 2017 12:56:54

sys_dev
От:
Зарегистрирован: 2011-06-22
Сообщения: 26
Репутация: +  0  -
Профиль   Отправить e-mail  

Как реализовать singleton?

4kpt_IV
Синглетон - это антипаттерн. Не надо его делать Ну а если все же надо, тогда пользуемся __getattr__, __setattr__ и их товарищам.
Ну как бы да. Но все же! Хочу получить примерно такое:


 class Proba:
    __slots__ = ['__a']
    def __init__(self, a=10):
        self.__a = a
    def set_a(self, value):
        self.__a = value
    def get_a(self):
        return self.__a
class ProbaSingletonWrapper(object):
    __instance = None
    def __new__(cls):
        if not cls.__instance:
            ProbaSingletonWrapper.__instance = object.__new__(cls)
        return ProbaSingletonWrapper.__instance
    def __getattr__(self, name):
        return getattr(self.__instance, name)
    def __setattr__(self, name):
        return setattr(self.__instance, name)

Но получаю это:
>>>p1 = ProbaSingletonWrapper()
>>> p1.get_a()
Traceback (most recent call last):
File “<stdin>”, line 1, in <module>
File “d:\personal\projects\python-workspace\proba\singleton.py”, line 24, in __getattr__
return getattr(self.__instance, name)
File “d:\personal\projects\python-workspace\proba\singleton.py”, line 24, in __getattr__
return getattr(self.__instance, name)
File “d:\personal\projects\python-workspace\proba\singleton.py”, line 24, in __getattr__
return getattr(self.__instance, name)

RecursionError: maximum recursion depth exceeded while calling a Python object

Что не так?



Офлайн

#4 Янв. 13, 2017 13:02:37

sys_dev
От:
Зарегистрирован: 2011-06-22
Сообщения: 26
Репутация: +  0  -
Профиль   Отправить e-mail  

Как реализовать singleton?

Кажется понял, мне надо создать объект Proba и его подавать в getattr()



Офлайн

#5 Янв. 13, 2017 13:11:13

4kpt_IV
Зарегистрирован: 2016-01-08
Сообщения: 999
Репутация: +  49  -
Профиль   Отправить e-mail  

Как реализовать singleton?

Вообще в __getttr__ лучше работать с __dict__ объекта.

Офлайн

#6 Янв. 13, 2017 13:15:42

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Как реализовать singleton?

Если не нужно какое-то особое поведение, то синглтон это просто класс без атрибутов объекта.

 class mySingleton:
    a = 1
    b = 2
print(mySingleton.a)
mySingleton.a = 23
print(mySingleton.a)



Офлайн

#7 Янв. 13, 2017 13:25:55

sys_dev
От:
Зарегистрирован: 2011-06-22
Сообщения: 26
Репутация: +  0  -
Профиль   Отправить e-mail  

Как реализовать singleton?

FishHook
Если не нужно какое-то особое поведение, то синглтон это просто класс без атрибутов объекта.
Но верно ли я понимаю что a и b будут созданы на стадии загрузки модуля, а не создании объекта mySingleton?
Просто мне надо чтобы в момент создания класса синглтон объект веб-драйвера создался, а в момент уничтожения класса синглтон объект веб-драйвера закрылся. Возможно надо написать дополнительно __init__() и __del__()



Офлайн

#8 Янв. 13, 2017 13:43:38

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Как реализовать singleton?

Ничего нет сложного в том, чтобы инициализировать атрибуты класса когда угодно.

   
class classproperty(object):
  
    def __init__(self, fget):
        self.fget = fget
  
    def __get__(self, owner, cls):
        return self.fget(cls)
  
 class mySingleton:
    _a = None
    @classproperty
    def a(cls):
        if cls._a is None:
            cls._a = get_my_property_a()
        return cls._a
   



Офлайн

#9 Янв. 14, 2017 00:09:46

sys_dev
От:
Зарегистрирован: 2011-06-22
Сообщения: 26
Репутация: +  0  -
Профиль   Отправить e-mail  

Как реализовать singleton?

Как-то так выходит.

 from selenium import webdriver
class Chrome(webdriver.Chrome):
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            cls._instance = super().__new__(cls, *args, **kwargs)
        return cls._instance



Офлайн

#10 Янв. 14, 2017 01:15:48

4kpt_IV
Зарегистрирован: 2016-01-08
Сообщения: 999
Репутация: +  49  -
Профиль   Отправить e-mail  

Как реализовать singleton?

Это стандартный синглетон. Так сказать, классический. Именно так создается синглетон во всех учебных руководствах

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version