Python:是';适当的';用类变量替换全局变量的步骤

Python:是';适当的';用类变量替换全局变量的步骤,python,global-variables,class-variables,Python,Global Variables,Class Variables,请善待我,我是Python初学者:-) 现在,我看到编写Python程序的“最佳实践”是将主代码包装在“main”函数中,并执行如果“\uuuu main\uuuu”==\uu name:测试以调用“main”函数 当然,这就需要在“main”函数中使用一系列global语句来访问全局变量 我想知道将全局变量收集到一个自定义类(比如\u v)中,并使用\u v.前缀引用变量是否更合适(或者“Pythonic”,如果您愿意的话) 另外,作为一个必然的问题,这会对性能或异常处理产生任何负面影响吗

请善待我,我是Python初学者:-)

现在,我看到编写Python程序的“最佳实践”是将主代码包装在“main”函数中,并执行
如果“\uuuu main\uuuu”==\uu name:
测试以调用“main”函数

当然,这就需要在“main”函数中使用一系列
global
语句来访问全局变量

我想知道将全局变量收集到一个自定义类(比如
\u v
)中,并使用
\u v.
前缀引用变量是否更合适(或者“Pythonic”,如果您愿意的话)

另外,作为一个必然的问题,这会对性能或异常处理产生任何负面影响吗


编辑:以下是程序的一般结构:

paramset = {
    0: { ...dict of params... }
    1: { ...dict of params... }
    2: { ...dict of params... }
    }

selector = 0
reset_requested = False
selector_change = False

def sighup_handler(signal,frame):
    global reset_requested
    logger.info('Caught SIGHUP, resetting to set #{0}'.format(new_selector))
    reset_requested = True
    selector = 0

def sigusr1_handler(signal,frame):
    global selector
    new_selector = (selector + 1) % len(paramset)
    logger.info('Caught SIGHUP, changing parameters to set #{0}'.format(new_selector))
    selector = new_selector
    selector_change = True

signal.signal(signal.SIGHUP, sighup_handler)
signal.signal(signal.SIGUSR1, sigusr1_handler)

def main():
    global reset_requested
    global selector
    global selector_change
    keep_running = True
    while keep_running
        logger.info('Processing selector {0}'.format(selector))
        for stage in [process_stage1, process_stage2, process_stage3]
            err, result = stage(paramset[selector])
            if err is not None:
                logger.critical('Stage failure! Err {0} details: {0}'.format(err, result))
                raise SystemError('Err {0} details: {0}'.format(err, result))
            else:
                logger.info('Stage success: {0}'.format(result))
            if reset_requested:
                stage_cleanup()
                reset_requested = False
            else:
                inter_stage_pause()
                if selector_change:
                    selector_change = False
                    break
        selector = (selector + 1) % len(paramset)

通常,最好的做法是避免使用全局变量,而只是通过方法调用将变量传递给需要它们的类/方法。示例:如果您正在制作一个计算器,请创建一个加法,该方法接受2个整数并返回一个整数。这与将2个输入整数和1个输出整数作为全局变量,并让add方法处理这些变量形成对比。

示例代码中缺少足够多的片段,因此很难得出任何确定的结论

事件驱动方法 解决这类问题的通常方法是使其完全由事件驱动。目前,代码主要是轮询。例如,
sighup\u处理程序
设置
reset\u requested=True
,而
main
中的
循环处理该请求。事件驱动方法将处理重置,这意味着直接调用
stage\u cleanup

def sighup_handler(signal,frame):
    logger.info('Caught SIGHUP, resetting to set #{0}'.format(new_selector))
    stage_cleanup()

使用共享变量初始化 在示例代码中,所有这些过程_阶段以及在这些阶段中循环的目的都不清楚。所有这些都可以放在事件驱动的上下文中吗?我不知道。如果不能,并且确实需要共享变量,那么您对类的建议将是一个自然选择。此类课程的开始可能如下所示:

class Main(object);

    def __init__(self):
        self.selector = 0
        self.selector_change = False
        signal.signal(signal.SIGHUP, self.sighup_handler)
        signal.signal(signal.SIGUSR1, self.sigusr1_handler)

    def sighup_handler(self, signal,frame):
        logger.info('Caught SIGHUP, resetting to set #{0}'.format(new_selector))
        stage_cleanup() 
        self.selector = 0

    def sigusr1_handler(self, signal,frame):
        new_selector = (selector + 1) % len(paramset)
        logger.info('Caught SIGHUP, changing parameters to set #{0}'.format(new_selector))
        self.selector = new_selector
        self.selector_change = True

    def mainloop(self):
        # Do here whatever polling is actually required.

if __name__ == '__main__':
    main = Main()
    main.mainloop()

同样,因为我不清楚轮询循环的真正用途,所以我没有尝试在上面的类中重现它的功能。

好吧,在我的情况下的“用例”是我必须截获几个信号(HUP、USR1和USR2),这些信号将激活一些标志,这些标志将由main()函数“在适当的时候”处理(即,向程序发送这些信号不会立即产生结果).在python中,诸如HUP、USR1之类的信号是使用
信号
模块进行截获的。文档。不需要全局变量。我知道。信号处理程序只设置一个标志。主函数中的主循环将定期检查标志,并在启动长流程之前更改流程的各种参数pepoluan,你能给我们看看你的代码(或它的最小工作子集)吗?如果我们看到您的尝试,我们将更容易提供有用的反馈。谢谢。我会在下班后编辑我的问题。@John1024我编辑了我的问题,只添加了相关的逻辑。谢谢。这不是一个问题,但很有助于了解问题的动机。感谢您的解释!活动dri遗憾的是,ven信号处理方法不适用,因为当请求重置时,如果某个阶段仍在运行,则该阶段必须运行到完成。这就是为什么我只在信号处理程序中设置一个标志,并让主循环处理阶段之间的标志。@pepoluan事件驱动信号处理程序设计用于处理问题类似于此。如果在“阶段”期间不能处理重置正在运行时,解决方案是在关键部分对HUP信号进行该阶段的处理,然后稍后将其取消阻止。甚至还有一种方法可以查看。信号处理是一门发展良好的艺术。嗯……这对我来说是新的。感谢链接!我刚刚注意到这些链接需要py3.3。如果您使用的是较旧版本的python,可能会有所帮助。