Python:用类变量替换全局变量“合适”吗

2024-06-15 02:13:52 发布

您现在位置:Python中文网/ 问答频道 /正文

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

现在,我看到编写Python程序的“最佳实践”是将主代码包装在“main”函数中,并执行if "__main__" == __name__:测试来调用“main”函数。在

这当然会导致在“main”函数中使用一系列global语句来访问全局变量。在

我想知道,将全局变量收集到一个自定义类中,比如_v,并使用_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)

Tags: infofalseformatnewsignalifmainlogger
2条回答

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

事件驱动方法

对于这类问题,通常的方法是使其完全由事件驱动。目前,代码主要是轮询。例如,sighup_handler设置reset_requested = Truemain中的while循环处理该请求。事件驱动的方法将直接处理重置,这意味着调用stage_cleanup

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


使用共享变量

在示例代码中,所有这些process_阶段以及在这些阶段之间循环的目的并不清楚。所有这些都可以放在事件驱动的上下文中吗?我不知道。如果不能,并且需要共享变量,那么您对类的建议将是一个自然的选择。这样一个类的开始可能看起来像:

^{pr2}$

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

通常,最佳实践是避免全局变量,而是通过方法调用将变量传递给需要它们的类/方法。例如:如果你在做一个计算器,那么做一个加法方法,它接受2个整数并返回一个整数。这与将2个输入整数和1个输出整数作为全局变量,并让add方法处理这些变量相反。在

相关问题 更多 >