def timeout(error_message=os.strerror(errno.ETIME)): def decorator(func): def _handle_timeout(signum, frame): raise Exception(error_message) def wrapper(*args, **kwargs): signal.signal(signal.SIGALRM, _handle_timeout) signal.alarm(args[1]) try: result = func(*args, **kwargs) finally: signal.alarm(0) return result return wrapper return decorator @timeout() def wait(title,second): wid = None if title: wid = subprocess.check_output(['xdotool', 'search', '--sync', '--name', title]) return wid wid = wait('Connection Manager',560)怎么优化这段代码,提高工作效率
时间: 2024-03-17 08:41:38 浏览: 19
这段代码中存在一些可以优化的地方:
1. 使用`subprocess.check_output`会启动一个新的进程,比较耗费时间,可以考虑使用`subprocess.Popen`来代替。
2. `signal.alarm`方法在使用`timeout`装饰器时会被多次调用,可以将其提到`decorator`函数中进行处理,避免多次调用。
3. 在`_handle_timeout`函数中直接抛出`Exception`可能会导致程序意外退出,可以自定义一个异常类来代替。
4. 在`decorator`函数中,由于`func`函数的参数可能会发生变化,可以使用`functools.wraps`来保留原函数的元信息。
下面是优化后的代码:
```python
import functools
import os
import errno
import signal
import subprocess
class TimeoutException(Exception):
pass
def timeout(seconds, error_message=os.strerror(errno.ETIME)):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
def _handle_timeout(signum, frame):
raise TimeoutException(error_message)
signal.signal(signal.SIGALRM, _handle_timeout)
signal.alarm(seconds)
try:
result = func(*args, **kwargs)
finally:
signal.alarm(0)
return result
return wrapper
return decorator
@timeout(560)
def wait(title):
wid = None
if title:
p = subprocess.Popen(['xdotool', 'search', '--sync', '--name', title], stdout=subprocess.PIPE)
wid, _ = p.communicate()
return wid
wid = wait('Connection Manager')
```
在优化后的代码中,使用`subprocess.Popen`代替`subprocess.check_output`启动新进程;将`signal.alarm`提到`decorator`函数中;使用自定义的异常类代替直接抛出`Exception`;使用`functools.wraps`来保留原函数的元信息。