请善待我,我是Python的初学者: - )
现在,我看到编写Python程序的'最佳实践'是将主代码包装在'main'函数中,并执行if "__main__" == __name__:
测试以调用'main'函数。
这当然导致必须在'main'函数中使用一系列global
语句来访问全局变量。
我想知道它是否更合适(或者'Pythonic',如果你愿意的话)将全局变量收集到一个自定义类中,比如_v
,并使用_v.
前缀来引用变量?
另外,作为一个必然结果的问题,是否会对绩效或异常处理产生负面影响?
编辑:以下是该计划的一般结构:
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)
答案 0 :(得分:2)
示例代码中缺少足够的部分,难以得出任何确定的结论。
此类问题的常用方法是使其完全由事件驱动。就目前而言,代码主要是轮询。例如,sighup_handler
在请求的reset_requested = True
进程中设置while
和main
循环。事件驱动的方法将处理重置,即直接调用stage_cleanup
:
def sighup_handler(signal,frame):
logger.info('Caught SIGHUP, resetting to set #{0}'.format(new_selector))
stage_cleanup()
在示例代码中,所有那些process_stages和循环阶段的目的尚不清楚。这一切都可以放在事件驱动的环境中吗?我不知道。如果它不能并且确实需要共享变量,那么您对类的建议将是一个自然的选择。这类课程的开头可能如下:
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()
同样,因为我不清楚轮询循环的真正目的,所以我没有尝试在上面的类中重现它的功能。
答案 1 :(得分:0)
通常,最佳做法是避免全局变量,而只是通过方法调用将变量传递给需要它们的类/方法。示例:如果要创建计算器,请创建一个需要2个int的加法方法并返回一个int。这与将2个输入整数和1个输出int作为全局变量形成对比,并且使用add方法可以处理这些变量。