请善待我,我是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)
示例代码中缺少足够多的部分,因此很难得出任何确定的结论。在
事件驱动方法
对于这类问题,通常的方法是使其完全由事件驱动。目前,代码主要是轮询。例如,
sighup_handler
设置reset_requested = True
和main
中的while
循环处理该请求。事件驱动的方法将直接处理重置,这意味着调用stage_cleanup
:使用共享变量
在示例代码中,所有这些process_阶段以及在这些阶段之间循环的目的并不清楚。所有这些都可以放在事件驱动的上下文中吗?我不知道。如果不能,并且需要共享变量,那么您对类的建议将是一个自然的选择。这样一个类的开始可能看起来像:
^{pr2}$同样,由于轮询循环的真正用途我不清楚,所以我没有尝试在上面的类中重现它的功能。在
通常,最佳实践是避免全局变量,而是通过方法调用将变量传递给需要它们的类/方法。例如:如果你在做一个计算器,那么做一个加法方法,它接受2个整数并返回一个整数。这与将2个输入整数和1个输出整数作为全局变量,并让add方法处理这些变量相反。在
相关问题 更多 >
编程相关推荐