2016-01-02 4 views
2

Я пытаюсь изучить шаблоны дизайна в Python. Подход к реализации глобальных переменных осуществляется через шаблон Borg.Borg Design Pattern

class Borg: 
    __shared_state = {} 
    def __init__(self): 
     self.__dict__ = self.__shared_state 

Это, кажется, словарь. Как я могу хранить более сложные структуры данных, например, фрейм данных Pandas или пользовательский класс, которые будут использоваться глобально?

ответ

3

На самом деле, это не рекомендованный подход, и я никогда не видел его в реальном коде.

Рекомендуемый подход заключается в использовании модуля в качестве модуля уже имеет «глобальное» пространство имен (см this answer для получения дополнительной информации о globals(), locals() и vars()).


Однако в интересах понимания:

То, что вы до сих пор является лишь основные рамки для общего состояния на уровне экземпляра. Что вам нужно теперь остальные государства вы хотите отслеживать:

class Config(Borg): 

    def __init__(self, config_file): 
     super(Config, self).__init__() 
     # load and parse file, saving settings to `self` 

Одним из недостатков этого метода является то, что вы можете иметь несколько экземпляров, потребляющих память, что все знаем то же самое. (Не так много памяти, правда.)

Другим методом выполнения «общего состояния» является создание только одного экземпляра, а затем класс всегда возвращает тот же экземпляр, который иначе известен как singleton.

class Config(object): 

    the_one = None 

    def __new__(cls, config): 
     if cls.the_one is None: 
      cls.the_one = Super(Config, cls).__new__(cls) 
      # load and parse file, saving settings to `cls.the_one` 
     return cls.the_one 

метод либо приведет к следующему:

>>> config = Config('my_config_file.cfg') 
>>> config.screen_size 
# whatever was saved during the loading and parsing of the config file 
# for 'screen_size' 
1

Это не рекомендуется:

class Borg: 
    __shared_state = {} 
    def __init__(self): 
     self.__dict__ = self.__shared_state # *** 

Там нет абсолютно никакой необходимости для различных объектов с одинаковым __dict__. Здесь вы делаете все экземпляры точно такими же данными. Вы также можете сделать объект одиночным и избегать создания избыточных объектов:

class Borg(object): 
    instance = None 
    def __new__(cls): 
     if cls.instance is None: 
      cls.instance = super(Borg, cls).__new__(cls) 
     return cls.instance 

>>> b1 = Borg() 
>>> b2 = Borg() 
>>> b1 is b2 
True 

Но почему это так? Модули представляют собой, по существу, одноэлементы с пространством имен, в котором вы можете хранить данные и функциональные возможности.

Я бы просто использовал модуль.

Как хранить более сложные структуры данных, скажем, dataframe панды или пользовательский класс, который будет использоваться в глобальном масштабе?

Простой - хранить данные в глобал модуля (например module.py), как это:

global_dataframe = pandas.DataFrame() 

class CustomClass: 
    """my Python class definition""" 

global_dataframe и CustomClass являются в настоящее время модуля Глобал уровня. Вы можете импортировать модуль, в котором они находятся, и ссылаться на них путем точечного поиска.

>>> import module 
>>> module.global_dataframe 
Empty DataFrame 
Columns: [] 
Index: [] 
>>> module.CustomClass 
<class module.CustomClass at 0x7fdf73f3d0b8>