Начиная с Python 3.7 (и в результате PEP-562 ), теперь это возможно с уровнем модуля __getattr__
:
Внутри вашего модуля поместите что-то вроде:
def _long_function():
# print() function to show this is called only once
print("Determining DOWNLOAD_FOLDER_PATH...")
# Determine the module-level variable
path = "/some/path/here"
# Set the global (module scope)
globals()['DOWNLOAD_FOLDER_PATH'] = path
# ... and return it
return path
def __getattr__(name):
if name == "DOWNLOAD_FOLDER_PATH":
return _long_function()
# Implicit else
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
Из этого должно быть ясно, что _long_function()
не выполняется при импорте вашего модуля, например ::
print("-- before import --")
import somemodule
print("-- after import --")
Результат только:
-- before import --
-- after import --
Но когда вы пытаетесь получить доступ к имени из модуля, будет вызван модуль уровня __getattr__
, который, в свою очередь, вызовет _long_function
, который выполнит долгосрочную задачу, кэшируйте его как переменную уровня модуля и возвращайте результат обратно к коду, который его вызвал.
Например, с первым блоком выше внутри модуля "somemodule.py", следующий код:
import somemodule
print("--")
print(somemodule.DOWNLOAD_FOLDER_PATH)
print('--')
print(somemodule.DOWNLOAD_FOLDER_PATH)
print('--')
производит:
--
Determining DOWNLOAD_FOLDER_PATH...
/some/path/here
--
/some/path/here
--
или, более четко:
# LINE OF CODE # OUTPUT
import somemodule # (nothing)
print("--") # --
print(somemodule.DOWNLOAD_FOLDER_PATH) # Determining DOWNLOAD_FOLDER_PATH...
# /some/path/here
print("--") # --
print(somemodule.DOWNLOAD_FOLDER_PATH) # /some/path/here
print("--") # --
Наконец, вы также можете реализовать __dir__
, как описывает PEP, если вы хотите указать (например, инструментам интроспекции кода), что DOWNLOAD_FOLDER_PATH
доступно .