使用Python 3.2.2进行多线程尝试:"AttributeError: 'str'对象没有属性'_initialized
我在使用以下Python 3.2.2代码时遇到了问题。这段代码是我用来测试另一个应用程序的反应时间的。我的想法是让另一个脚本(可以是任何类型的)传递给这个计时程序,并对环境进行一些修改。这个脚本应该在一个单独的线程中运行,这样我就可以从脚本开始时就开始计时,而不是等到结束时。接下来的代码则是用来计时应用程序对那个脚本的反应。我试着参考了threading
模块的文档来创建这个代码,我相信我已经仔细阅读过,但我总是遇到以下错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python32\lib\threading.py", line 669, in start
if not self._initialized:
AttributeError: 'str' object has no attribute '_initialized'
这是线程类的定义。
import threading, ...
class AsyncScript(threading.Thread):
def __init__(self, s):
self.script = s
def run(self):
print ("Beginning script...")
try:
os.system("cmd /k " + self.script)
except:
sys.exit("Error running script " + self.script)
这个类在脚本的其他地方被调用,方式是AsyncScript.start(options.script)
,其中options
类包含传递给脚本的选项(使用argparse
模块)。
你觉得我可能哪里做错了呢?
好的,更新一下。下面这个(简化版的)代码确实可以工作,老实说我也不太明白为什么——我看不出有什么不同。
import threading
class AsyncScript(threading.Thread):
def __init__(self, s):
threading.Thread.__init__(self)
self.script = s
def run(self):
print("This would run script " + self.script)
AsyncScript("sample script path string").start()
输出结果是,恰如其分,
这将运行脚本示例脚本路径字符串
除了包含threading.Thread.__init__(self)
这一行,我之前在早期版本的代码中加过这个,但没有成功,我现在真的不太确定这里有什么不同。我错过了什么呢?
3 个回答
你的 self.script
没有被初始化,但你有 self.s
- 试着用它吧。
在脚本的其他地方,这段代码是通过
AsyncScript.start(options.script)
来调用的。
这个调用是错误的。你把 threading.Thread
的无参数(不算 self
)的 start
方法当成了你的脚本字符串来用,而不是先创建一个 AsyncScript
类的实例(把字符串传给 __init__
),然后再调用这个实例的线程对象的 .start()
方法。显然,一个字符串不是一个线程,所以当你把字符串当作 self
传给线程代码时,它会出错。正确的写法应该是 AsyncScript(options.script).start()
。
如果你已经在一个单独的进程中运行脚本,那就不需要使用线程。可以用 subprocess
来代替 os.system()
。
你不需要去继承 Thread
类来创建一个线程:
Thread(target=func, args=func_args).start()
我不太明白这里有什么不同。我错过了什么吗?
这里有两个不同之处:
AsyncScript.start(options.script)
和AsyncScript(options.script).start()
。AsyncScript
是一个类对象,而AsyncScript(options.script)
是这个类的一个实例。AsyncScript.start(options.script)
调用的是一个未绑定的.start
方法。它期望第一个参数是一个 AsyncScript 实例,而不是一个字符串options.script
。正确的调用方法是obj.method()
。在你的例子中,obj = AsyncScript(options.script)
。在
AsyncScript.__init__()
方法中有threading.Thread.__init__(self)
的存在。如果你不调用
threading.Thread.__init__(self)
,那么线程的属性,比如_initialized
就不会被创建或定义。