如何在 windows 上的多个进程上存储持久设置
How to store persistent settings over multiple processes on windows
我的程序在启动时处理命令行参数,从设置文件中读取一些设置并覆盖我在设置 class 中的标准值。此设置实例设置一次,仅在之后读取。我可以在程序的任何地方导入设置并使用它们。例如,目录的路径由用户在启动时提供,稍后在程序中使用。
问题是我想使用多处理并且我必须使用 Windows。在 Windows 上,我必须使用 spawn method 创建一个新进程,它从一个新的 python 解释器进程开始,并删除对设置所做的所有更改。 (下面的示例代码)
我想知道是否有更智能的方式来存储设置。
# settings.py
class Settings:
path = None
settings = Settings()
# main.py
import multiprocessing
from settings import settings
def print_path():
print(f"Path: {settings.path}")
if __name__ == "__main__":
settings.path = "test.csv" # user input
with multiprocessing.Pool(4) as pool:
pool.apply(func=print_path) # prints "Path: None" but I'd like to see "Path: test.csv"
正如我评论的那样,您想将所有与初始化设置相关的代码放在一个只会由主进程执行的代码块中。最简单的方法是创建一个名为 init_settings
的函数并将代码放在那里,该函数将由 if __name__ == '__main__':
块内的代码或由此类块内调用的函数调用。可以保留全局范围 class 定义(它们的执行开销很小),尤其是在子流程需要它们的情况下。然后您可以使用每个池进程的设置初始化一个全局变量,这样就不必为每个提交的任务传递它,而只需为池中的每个进程传递一次。
不过,我有点困惑。你有 from settings import settings
然后你用 settings = Settings()
.
破坏 settings
总体思路如下:
# Assumption that this is used by all tasks and must be initialized
class Settings:
...
def init_settings()
"""
Function responsible for creating the settings instance.
"""
# only this function needs to do this import:
from settings import settings
...
settings = Settings()
# Initialize this
settings.path = "test.csv"
... # etc.
return settings
def init_pool(the_settings):
""" Initialize global variable for each process in the pool """
global settings
settings = the_settings
def print_path():
print(f"Path: {settings.path}")
if __name__ == '__main__':
import multiprocessing
settings = init_settings()
# Initialize the pool with the settings as a global variable
with multiprocessing.Pool(4, initializer=init_pool, initargs=(settings,)) as pool:
pool.apply(func=print_path) # blocks until complete
我的程序在启动时处理命令行参数,从设置文件中读取一些设置并覆盖我在设置 class 中的标准值。此设置实例设置一次,仅在之后读取。我可以在程序的任何地方导入设置并使用它们。例如,目录的路径由用户在启动时提供,稍后在程序中使用。
问题是我想使用多处理并且我必须使用 Windows。在 Windows 上,我必须使用 spawn method 创建一个新进程,它从一个新的 python 解释器进程开始,并删除对设置所做的所有更改。 (下面的示例代码)
我想知道是否有更智能的方式来存储设置。
# settings.py
class Settings:
path = None
settings = Settings()
# main.py
import multiprocessing
from settings import settings
def print_path():
print(f"Path: {settings.path}")
if __name__ == "__main__":
settings.path = "test.csv" # user input
with multiprocessing.Pool(4) as pool:
pool.apply(func=print_path) # prints "Path: None" but I'd like to see "Path: test.csv"
正如我评论的那样,您想将所有与初始化设置相关的代码放在一个只会由主进程执行的代码块中。最简单的方法是创建一个名为 init_settings
的函数并将代码放在那里,该函数将由 if __name__ == '__main__':
块内的代码或由此类块内调用的函数调用。可以保留全局范围 class 定义(它们的执行开销很小),尤其是在子流程需要它们的情况下。然后您可以使用每个池进程的设置初始化一个全局变量,这样就不必为每个提交的任务传递它,而只需为池中的每个进程传递一次。
不过,我有点困惑。你有 from settings import settings
然后你用 settings = Settings()
.
settings
总体思路如下:
# Assumption that this is used by all tasks and must be initialized
class Settings:
...
def init_settings()
"""
Function responsible for creating the settings instance.
"""
# only this function needs to do this import:
from settings import settings
...
settings = Settings()
# Initialize this
settings.path = "test.csv"
... # etc.
return settings
def init_pool(the_settings):
""" Initialize global variable for each process in the pool """
global settings
settings = the_settings
def print_path():
print(f"Path: {settings.path}")
if __name__ == '__main__':
import multiprocessing
settings = init_settings()
# Initialize the pool with the settings as a global variable
with multiprocessing.Pool(4, initializer=init_pool, initargs=(settings,)) as pool:
pool.apply(func=print_path) # blocks until complete