Лучший способ хранить и использовать большой текстовый файл в Python

StackOverflow https://stackoverflow.com/questions/158546

  •  03-07-2019
  •  | 
  •  

Вопрос

Я создаю сетевой сервер для клона boggle, который я написал на Python, который принимает пользователей, решает доски и оценивает действия игрока.Размер файла словаря, который я использую, составляет 1,8 МБ (словарь ENABLE2K), и мне нужно, чтобы он был доступен нескольким классам решателей игр.Прямо сейчас у меня так, что каждый класс последовательно перебирает файл и генерирует хеш-таблицу (ассоциативный массив), но чем больше классов решателя я создаю, тем больше памяти он занимает.

Я хотел бы один раз импортировать файл словаря и передать его каждому экземпляру решателя по мере необходимости.Но как лучше всего это сделать?Должен ли я импортировать словарь в глобальное пространство, а затем обращаться к нему в классе решателя как globals()['dictionary']?Или мне следует импортировать словарь, а затем передать его в качестве аргумента конструктору класса?Один из них лучше другого?Есть ли третий вариант?

Это было полезно?

Решение

Если вы создадите модуль словаря.py, содержащий код, который читает файл и создает словарь, этот код будет выполнен только при первом импорте.Дальнейший импорт вернет ссылку на существующий экземпляр модуля.Таким образом, ваши классы могут:

import dictionary

dictionary.words[whatever]

где словарь.py имеет:

words = {}

# read file and add to 'words'

Другие советы

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

Это действительно единственная разница.После создания объекта словаря вы привязываете новые ссылки только по мере его передачи, если только вы явно не выполняете глубокое копирование.Имеет смысл, что он создается централизованно один и только один раз, пока каждый экземпляр решателя не требует частной копии для модификации.

Адам, помни это в Python, когда говоришь:

a = read_dict_from_file()
b = a

...ты на самом деле не копирование a, и, таким образом, используя больше памяти, вы просто делаете b еще одна ссылка на тот же объект.

Так что в основном любой предлагаемые вами решения будут намного лучше с точки зрения использования памяти.В общем, читайте в словаре один раз а затем держитесь за ссылку на это.Независимо от того, делаете ли вы это с глобальной переменной, передаете ли ее каждому экземпляру или что-то еще, вы будете ссылаться на один и тот же объект, а не дублировать его.

Какой из них наиболее питонический?Это еще одна банка червей, но лично я бы сделал вот что:

def main(args):
  run_initialization_stuff()
  dictionary = read_dictionary_from_file()
  solvers = [ Solver(class=x, dictionary=dictionary) for x in len(number_of_solvers) ]

ХТХ.

В зависимости от того, что содержит ваш dict, вас могут заинтересовать модули «shelf» или «anydbm».Они предоставляют вам интерфейсы, подобные диктовке (просто строки в качестве ключей и элементов для «anydbm», строки в качестве ключей и любой объект Python в качестве элемента для «полки»), но данные на самом деле находятся в файле DBM (gdbm, ndbm, dbhash, bsddb, в зависимости от того, что доступно на платформе.) Вероятно, вы все равно захотите разделить реальную базу данных между классами, как вы просите, но это позволит избежать шага анализа текстового файла, а также сохранения всего этого -бит памяти.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top