How can I resolve the 'TypeError: 'list' object is not callable' error in this threaded pyside code that seems to work fine in a similar case?
How can I resolve the 'TypeError: 'list' object is not callable' error in this threaded pyside code that seems to work fine in a similar case?
我的错误的完整回溯是:
> python zthreadtest_tjedit.py
None
Traceback (most recent call last):
File "zthreadtest_tjedit.py", line 17, in run self.function()
TypeError: 'list' object is not callable
很抱歉,这段代码有点特定于系统,可能不会作为大多数人的可执行示例。希望该解决方案足够简单,可以让某人立即看到。如果您不是使用当前导入的 zpool 的 运行 zfs,而是在安装了 weir.zfs 模块的 *nix 平台上,它将 return 一个包含非线程代码的空列表启用(请参阅代码中的注释以切换线程)。启用线程模块后,它会抛出如上所示的错误。
令我困惑的是,来自 Jo Plaete (https://joplaete.wordpress.com/2010/07/21/threading-with-pyqt4/) 的第二段代码运行没有错误,我只是根据需要修改了这段代码。
编辑:这个导致错误的差异可能与我的代码中使用的列表对象有关,而不是她的,但我仍然需要让我的工作。
我的问题是:如何解决我的错误以使我的线程模块正确运行?
这看起来很简单,但我完全被难住了。如此之多以至于这是我在任何帮助论坛上发布的第一个问题!我希望我已经正确地提出了我的问题,我很感激任何帮助。
我的代码,来自更大的 pyside gui 程序:
import PySide, sys
from PySide import QtCore, QtGui
from PySide.QtCore import *
from PySide.QtGui import *
import re, subprocess, threading
from weir import zfs
class WorkerThread(QThread):
def __init__(self, function):
QThread.__init__(self)
self.function = function
def __del__(self):
self.wait()
def run(self):
self.function()
return
class MainZ(QMainWindow):
def __init__(self):
super(MainZ, self).__init__()
# print(self)
# imported_pools = self.get_imported() # No threading
imported_pools = self.thread_test() # Use threading module
print(imported_pools)
def thread_test(self):
self.threader = WorkerThread(self.get_imported())
self.threader.start()
def get_imported(self):
pool_string = subprocess.getoutput(
'zpool list |grep -v ^NAME.*SIZE.*ALLOC |grep -o ^[a-Z0-9]*')
imported_pools = re.split(r'\s *', pool_string)
return imported_pools
app = QApplication(sys.argv)
form = MainZ()
app.exec_()
我从 Jo Plaete 建模的代码对我没有错误:
import sys, time
from PySide import QtCore, QtGui
class GenericThread(QtCore.QThread):
def __init__(self, function, *args, **kwargs):
QtCore.QThread.__init__(self)
self.function = function
self.args = args
self.kwargs = kwargs
def __del__(self):
self.wait()
def run(self):
self.function(*self.args,**self.kwargs)
return
class MyApp(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setGeometry(300, 300, 280, 600)
self.setWindowTitle('threads')
self.layout = QtGui.QVBoxLayout(self)
self.testButton = QtGui.QPushButton("test")
self.connect(self.testButton, QtCore.SIGNAL("released()"), self.test)
self.listwidget = QtGui.QListWidget(self)
self.layout.addWidget(self.testButton)
self.layout.addWidget(self.listwidget)
def add(self, text):
""" Add item to list widget """
print("Add: " + text)
self.listwidget.addItem(text)
self.listwidget.sortItems()
def addBatch(self,text="test",iters= 5,delay=0.2):
""" Add several items to list widget """
for i in range(iters):
time.sleep(delay) # artificial time delay
self.add(text+" "+str(i))
def test(self):
self.listwidget.clear()
self.genericThread = GenericThread(
self.addBatch,"from generic thread ",delay=0.3)
self.genericThread.start()
# run
app = QtGui.QApplication(sys.argv)
test = MyApp()
test.show()
app.exec_()
self.threader = WorkerThread(self.get_imported())
应该阅读
self.threader = WorkerThread(self.get_imported)
创建线程时,你想传递函数本身,而不是调用函数的结果(这是一个列表)。
我的错误的完整回溯是:
> python zthreadtest_tjedit.py
None
Traceback (most recent call last):
File "zthreadtest_tjedit.py", line 17, in run self.function()
TypeError: 'list' object is not callable
很抱歉,这段代码有点特定于系统,可能不会作为大多数人的可执行示例。希望该解决方案足够简单,可以让某人立即看到。如果您不是使用当前导入的 zpool 的 运行 zfs,而是在安装了 weir.zfs 模块的 *nix 平台上,它将 return 一个包含非线程代码的空列表启用(请参阅代码中的注释以切换线程)。启用线程模块后,它会抛出如上所示的错误。
令我困惑的是,来自 Jo Plaete (https://joplaete.wordpress.com/2010/07/21/threading-with-pyqt4/) 的第二段代码运行没有错误,我只是根据需要修改了这段代码。 编辑:这个导致错误的差异可能与我的代码中使用的列表对象有关,而不是她的,但我仍然需要让我的工作。
我的问题是:如何解决我的错误以使我的线程模块正确运行?
这看起来很简单,但我完全被难住了。如此之多以至于这是我在任何帮助论坛上发布的第一个问题!我希望我已经正确地提出了我的问题,我很感激任何帮助。
我的代码,来自更大的 pyside gui 程序:
import PySide, sys
from PySide import QtCore, QtGui
from PySide.QtCore import *
from PySide.QtGui import *
import re, subprocess, threading
from weir import zfs
class WorkerThread(QThread):
def __init__(self, function):
QThread.__init__(self)
self.function = function
def __del__(self):
self.wait()
def run(self):
self.function()
return
class MainZ(QMainWindow):
def __init__(self):
super(MainZ, self).__init__()
# print(self)
# imported_pools = self.get_imported() # No threading
imported_pools = self.thread_test() # Use threading module
print(imported_pools)
def thread_test(self):
self.threader = WorkerThread(self.get_imported())
self.threader.start()
def get_imported(self):
pool_string = subprocess.getoutput(
'zpool list |grep -v ^NAME.*SIZE.*ALLOC |grep -o ^[a-Z0-9]*')
imported_pools = re.split(r'\s *', pool_string)
return imported_pools
app = QApplication(sys.argv)
form = MainZ()
app.exec_()
我从 Jo Plaete 建模的代码对我没有错误:
import sys, time
from PySide import QtCore, QtGui
class GenericThread(QtCore.QThread):
def __init__(self, function, *args, **kwargs):
QtCore.QThread.__init__(self)
self.function = function
self.args = args
self.kwargs = kwargs
def __del__(self):
self.wait()
def run(self):
self.function(*self.args,**self.kwargs)
return
class MyApp(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setGeometry(300, 300, 280, 600)
self.setWindowTitle('threads')
self.layout = QtGui.QVBoxLayout(self)
self.testButton = QtGui.QPushButton("test")
self.connect(self.testButton, QtCore.SIGNAL("released()"), self.test)
self.listwidget = QtGui.QListWidget(self)
self.layout.addWidget(self.testButton)
self.layout.addWidget(self.listwidget)
def add(self, text):
""" Add item to list widget """
print("Add: " + text)
self.listwidget.addItem(text)
self.listwidget.sortItems()
def addBatch(self,text="test",iters= 5,delay=0.2):
""" Add several items to list widget """
for i in range(iters):
time.sleep(delay) # artificial time delay
self.add(text+" "+str(i))
def test(self):
self.listwidget.clear()
self.genericThread = GenericThread(
self.addBatch,"from generic thread ",delay=0.3)
self.genericThread.start()
# run
app = QtGui.QApplication(sys.argv)
test = MyApp()
test.show()
app.exec_()
self.threader = WorkerThread(self.get_imported())
应该阅读
self.threader = WorkerThread(self.get_imported)
创建线程时,你想传递函数本身,而不是调用函数的结果(这是一个列表)。