Python中装饰器自动调用被装饰函数的问题修复方案
解决单例进程装饰器自动执行函数的问题
原代码的核心问题是装饰器在修饰函数时就直接执行了目标函数,导致hello()会自动运行。以下是修改后的代码,实现仅在if __name__ == "__main__"块中调用才执行的需求:
from multiprocessing import shared_memory import time import os import sys def singleton_process(*args, **kwargs): def wrapper(func): def inner(): flag = True shm = None try: shared_name = kwargs.get('shared_name') shm = shared_memory.SharedMemory( name=shared_name, create=True, size=1 ) print("The first copy of the script has been launched.") return func() except FileExistsError: flag = False print("Another instance of the script is already running.") sys.exit(1) except KeyboardInterrupt: if shm: shm.close() shm.unlink() raise finally: if flag and shm: shm.close() try: shm.unlink() except FileNotFoundError: pass return inner return wrapper @singleton_process(shared_name='my_lock') def hello(): c = 0 while True: c += 1 if c == 5: break pid = os.getpid() print(f'PID={pid}. Script is working...') time.sleep(1) return True if __name__ == '__main__': hello()
关键修改说明
- 调整装饰器结构:原
wrapper函数直接执行func(),现在改为返回inner函数,只有当显式调用被装饰后的hello()时,才会触发单例检查和目标函数执行。 - 修复变量未定义问题:初始化
shm为None,避免在异常处理块中访问未创建的共享内存对象导致NameError。 - 优化异常处理:在
KeyboardInterrupt中先判断shm是否存在再进行清理,同时重新抛出异常保证程序正常终止流程。 - 显式触发执行:在
if __name__ == '__main__'块中调用hello(),确保只有脚本作为主程序运行时才会执行逻辑,导入脚本时不会自动运行。
内容的提问来源于stack exchange,提问作者Maxim Postnikov
相关产品推荐
相关产品推荐

