Может ли python загружать данные из файла «по требованию» при обращении к переменной? - PullRequest
0 голосов
/ 06 января 2020

Я использую python 3.6, и у меня есть длинные списки номеров идентификаторов, которые я хотел бы кэшировать в файлах, но загружать их в память только при необходимости. В идеале я хотел бы, чтобы они отображались как переменные типа списка, которые загружаются из файла при обращении к ним, следующим образом.

""" contents of a library file, canned_lists.py """
list_of_ids = []
def event_driven_on_access_of_list_of_ids():
    # don't allow access to the empty list yet
    global list_of_ids
    with open("the_id_file.csv", "r") as f:
        list_of_ids = f.readlines()
    # now the list is ready, it can be accessed
""" contents of a calling file, script.py """
import canned_lists
for id in canned_lists.list_of_ids:  # at this point, list_of_ids should populate from a file
    print("do something with the ids")

Альтернативным вариантом А будет использование функции, а не Переменная. Это работает и действительно неплохо, но с эстетической точки зрения я бы хотел импортировать список и использовать список, а не функцию.

""" contents of a library file, canned_lists.py """
def get_list_of_ids():
    with open("the_file.csv", "r") as f:
        return f.readlines()

Альтернативным вариантом B было бы просто сохранить данные в коде. В списках может быть почти 20 000 идентификаторов, поэтому вариант B неудобен и сложен в управлении. Это также заставляет PyCharm сообщать мне, что размеры моих файлов превышают настроенные ограничения функций Code Insight. Я мог бы, возможно, увеличить пределы, но кажется более разумным просто переместить данные из кода. ? Или у кого-нибудь есть идея получше? Я, вероятно, реализую альтернативу А, поскольку она совершенно функциональна, но мне не терпится поучиться у более продвинутых питонистов.

1 Ответ

1 голос
/ 06 января 2020

Вы можете использовать свойство в контексте класса, что вызывает функцию, вызываемую при доступе к переменной:

class X:
    @property
    def thing(self):
        return 42

print(X().thing) # prints 42, note no function call syntax

Две вещи, на которые следует обратить внимание: (1 ) каждый доступ к свойству будет вызывать функцию, поэтому вы можете кэшировать результат в классе для производительности; (2) обычно предполагается, что доступ к свойствам будет быстрым, то есть пользователи вашего кода не будут ожидать, что доступ к свойству будет выполнять медленную файловую операцию (что нарушит принцип наименьшего сюрприза).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...