线程回调函数中的ValueError - 尝试更新FTP进度 [英] ValueError in Thread callback function - Trying to update FTP progress

查看:250
本文介绍了线程回调函数中的ValueError - 尝试更新FTP进度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来的线程,并且遇到了一些麻烦,让我的工作者函数更新GUI。我有两个变量'bytes_so_far'和'size',我试图传回GUI实例,但是当我运行它时,我得到一个'ValueError:太多值来解压缩'。

I'm new to threads and having some trouble getting my worker function to update the GUI. I have two variables 'bytes_so_far' and 'size' that I'm trying to pass to back to the GUI instance but when I run it I get a 'ValueError: too many values to unpack'.

import time
import os, sys, wx
from ftplib import FTP_TLS

from threading import Thread
from wx.lib.pubsub import Publisher

########################################################################
class TestThread(Thread):
    """Test Worker Thread Class."""

    #----------------------------------------------------------------------
    def __init__(self):
        """Init Worker Thread Class."""
        Thread.__init__(self)
        self.start()    # start the thread

    #----------------------------------------------------------------------
    def run(self):
        """Run Worker Thread."""
        # This is the code executing in the new thread.
        HOST = '127.0.0.1'
        USERID = 'User'
        PASSWD = 'Passwd'
        FILE = r'C:\Myfile.zip'


        BLOCKSIZE = 57344
        try:
            ftp = FTP_TLS(HOST)
            ftp.login(USERID, PASSWD)
            ftp.prot_p()
            ftp.voidcmd("TYPE I")
            f = open(FILE, 'rb')
            datasock, esize = ftp.ntransfercmd(
                    'STOR %s' % os.path.basename(FILE))
            size = os.stat(FILE)[6]
            bytes_so_far = 0
            while 1:
                buf = f.read(BLOCKSIZE)
                if not buf:
                    break
                datasock.sendall(buf)
                bytes_so_far += len(buf)
                msg = [bytes_so_far, size]
                Publisher().sendMessage("update", msg)
        except: raise
        finally:
            try:
                datasock.close()
                f.close()
                ftp.voidresp()
                ftp.quit()
                print 'Complete...'
            except: pass

        wx.CallAfter(Publisher().sendMessage, "update", "Thread finished!")

########################################################################
class MyForm(wx.Frame):

    #----------------------------------------------------------------------
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "Tutorial")

        # Add a panel so it looks the correct on all platforms
        panel = wx.Panel(self, wx.ID_ANY)
        self.displayLbl = wx.StaticText(panel, label="Amount of time since thread started goes here")
        self.btn = btn = wx.Button(panel, label="Start Thread")
        self.gauge = wx.Gauge(panel, -1, 100, size=(370, 24))

        btn.Bind(wx.EVT_BUTTON, self.onButton)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.displayLbl, 0, wx.ALL|wx.CENTER, 5)
        sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
        sizer.Add(self.gauge, 0, wx.ALL|wx.CENTER, 5)
        panel.SetSizer(sizer)

        # create a pubsub receiver
        Publisher().subscribe(self.updateDisplay, "update")

    #----------------------------------------------------------------------
    def onButton(self, event):
        """
        Runs the thread
        """
        TestThread()
        self.displayLbl.SetLabel("Thread started!")
        btn = event.GetEventObject()
        btn.Disable()

    #----------------------------------------------------------------------
    def updateDisplay(self, msg):
        """
        Receives data from thread and updates the display
        """
        print msg.data
        bytes_so_far, size = msg.data
        k = 100 * bytes_so_far / size
        self.displayLbl.SetLabel("\rSent %d of %d bytes %.1f%%\r" % (bytes_so_far, size, 100 * bytes_so_far / size))
        self.gauge.SetValue(k)
        self.btn.Enable()

#----------------------------------------------------------------------
# Run the program
if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = MyForm().Show()
    app.MainLoop()

错误如下:

Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\_core.py", line 14640, in <lambda>
    lambda event: event.callable(*event.args, **event.kw) )
  File "C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\lib\pubsub\pubsub1\pub.py", line 750, in sendMessage
    self.__topicTree.sendMessage(aTopic, message, onTopicNeverCreated)
  File "C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\lib\pubsub\pubsub1\pub.py", line 423, in sendMessage
    deliveryCount += node.sendMessage(message)
  File "C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\lib\pubsub\pubsub1\pub.py", line 261, in sendMessage
    listener(message)
  File "F:\Programming\Tests\wxThread_FTP_Funtion.py", line 98, in updateDisplay
    bytes_so_far, size = msg.data
ValueError: too many values to unpack


推荐答案

消息

  File "G:\Programming\Tests\wxThread_FTP_Funtion.py", line 126, in updateDisplay
    bytes_so_far, size = list

表示将变量 list 分配给变量 bytes_so_far,size 太多的unpack值错误表明 list 中有超过2个元素。

indicates that the error is occurring when the variable list is assigned to variables bytes_so_far, size. The too many values to unpack error indicates that list has more than 2 elements in it.

但是你的代码看起来并不符合这个错误,因为没有行 bytes_so_far,size = list in你的示例,所以它似乎有一些其他版本的代码在那里,可能会使错误的原因更清楚。

But your code does not seem to match that error, since there is no line bytes_so_far, size = list in your sample, so it seems there is some other version of the code out there somewhere that might make the reason for the error more clear.

编辑:

感谢您的更新。错误应该是由于这个调用:

Thanks for the update. The error should be due to this call:

wx.CallAfter(Publisher().sendMessage, "update", "Thread finished!")

当updateDisplay运行这行代码时,

When updateDisplay runs this line of code,

bytes_so_far, size = msg.data

msg.data 包含字符串线程完成!,python尝试按顺序将字符串解压为单个字符将它们传递给每个分配的变量bytes_so_far和size,这导致太多的值来解开消息,即使在它的表面上只有一个要分配的值(字符串),你可能希望需要比x值更多的解包消息。

msg.data contains the string "Thread finished!", python attempts to unpack the string into its individual characters in order to pass those into each of the assigned variables bytes_so_far and size, which leads to the too many values to unpack message even though on the face of it there is only one value to assign (the string) and you might expect a need more than x values to unpack message.

这篇关于线程回调函数中的ValueError - 尝试更新FTP进度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆