Python:启动类方法时线程不起作用

标签 python multithreading class methods

import urllib.request
import urllib
import shutil
import os
import os.path
import sys
import time
import threading

class downloadFile:

    def __init__(self, downloadLink, downloadPath, onDiskName):
        self.downloadSize = urllib.request.urlopen(downloadLink).length
        self.downloadLink = downloadLink
        self.downloadPath = downloadPath
        self.onDiskName = onDiskName
        self.hardPath = os.path.join(self.downloadPath, self.onDiskName)

    def returnMode(self, returnMode = 'stats'):
        if returnMode == 'stats':
            return [self.downloadLink, self.downloadPath, self.onDiskName, self.downloadSize]
        elif returnMode == 'printedStats':
            print('self.downloadLink = ' + self.downloadLink)
            print('self.downloadPath = ' + self.downloadPath)
            print('self.onDiskName = ' + self.onDiskName)
            print('self.downloadSize = ' + self.downloadSize)
            print('self.hardPath = ' + self.hardPath)
            return [self.downloadLink, self.downloadPath, self.onDiskName, self.downloadSize, self.hardPath]

    def executeDownload(self):
        self.downloadStart = time.strftime("[%H:%M:%S] ")
        with urllib.request.urlopen(self.downloadLink) as response, open(self.hardPath, 'wb') as currentFile:
            shutil.copyfileobj(response, currentFile)
        currentFile.close()
        self.downloadEnd = time.strftime("[%H:%M:%S] ")

    def downloadStats(self):
        currentFileSize = os.path.getsize(self.hardPath)
        percentManifested = int(currentFileSize/(self.downloadSize/100))
        return [currentFileSize, percentManifested]

    def liveDownloadStats(self):
        if os.path.isfile(self.hardPath) == False:
            time.sleep(1)
        statList = self.downloadStats()
        while statList[0] < self.downloadSize:
            sys.stdout.write("\r" + self.downloadStart + " Downloading {0}... ".format(self.onDiskName) + "[{0}%]".format(statList[1]))
            sys.stdout.flush()
        sys.stdout.write("\r" + self.downloadStart + " Downloading {0}... ".format(self.onDiskName) + "[{0}%]".format(statList[1]))
        sys.stdout.write("\n")


server = downloadFile("https://s3.amazonaws.com/Minecraft.Download/versions/1.8/minecraft_server.1.8.jar", "C:/Users/my-username/Desktop/", "minecraftServer.jar")
t1 = threading.Thread(target=server.executeDownload())
t2 = threading.Thread(target=server.liveDownloadStats())
t2.start()
t1.start()
time.sleep(100)

一旦文件出现,这应该开始打印正在下载的文件的下载百分比。我看到的是文件出现了,不久之后我得到输出,表明它已 100% 下载。我看不出我在这里到底做错了什么。

最佳答案

问题在于,每次它检查当前下载的数据到需要下载的数据时,它都不会更新变量。因此,当循环出现时,它会比较相同的数字,直到出现某种结果。它被困在这个循环中,当某些东西导致它退出时,我不确定是什么,它继续到下载完成的下一行代码打印。

import urllib.request
import urllib
import shutil
import os
import os.path
import sys
import time
import threading

class downloadFile:

    def __init__(self, downloadLink, downloadPath, onDiskName):
        self.downloadSize = urllib.request.urlopen(downloadLink).length
        self.downloadLink = downloadLink
        self.downloadPath = downloadPath
        self.onDiskName = onDiskName
        self.hardPath = os.path.join(self.downloadPath, self.onDiskName)

    def returnMode(self, returnMode = 'stats'):
        if returnMode == 'stats':
            return [self.downloadLink, self.downloadPath, self.onDiskName, self.downloadSize]
        elif returnMode == 'printedStats':
            print('self.downloadLink = ' + self.downloadLink)
            print('self.downloadPath = ' + self.downloadPath)
            print('self.onDiskName = ' + self.onDiskName)
            print('self.downloadSize = ' + self.downloadSize)
            print('self.hardPath = ' + self.hardPath)
            return [self.downloadLink, self.downloadPath, self.onDiskName, self.downloadSize, self.hardPath]

    def executeDownload(self):
        self.downloadStart = time.strftime("[%H:%M:%S] ")
        with urllib.request.urlopen(self.downloadLink) as response, open(self.hardPath, 'wb') as currentFile:
            shutil.copyfileobj(response, currentFile)
        currentFile.close()
        self.downloadEnd = time.strftime("[%H:%M:%S] ")

    def downloadStats(self):
        currentFileSize = os.path.getsize(self.hardPath)
        percentManifested = int(currentFileSize/(self.downloadSize/100))
        return [currentFileSize, percentManifested]

    def liveDownloadStats(self):
        if os.path.isfile(self.hardPath) == False:
            time.sleep(1)
        statList = self.downloadStats()
        while statList[0] < self.downloadSize:
            sys.stdout.write("\r" + self.downloadStart + " Downloading {0}... ".format(self.onDiskName) + "[{0}%]".format(statList[1]))
            sys.stdout.flush()
            statList = self.downloadStats() #This is the extra line of code used to update the variable before comparing on the next while loop.
        sys.stdout.write("\r" + self.downloadStart + " Downloading {0}... ".format(self.onDiskName) + "[{0}%]".format(statList[1]))
        sys.stdout.write("\n")

def Main():
    server = downloadFile("https://s3.amazonaws.com/Minecraft.Download/versions/1.8/minecraft_server.1.8.jar", "C:/Users/my-username/Desktop/", "minecraftServer.jar")
    t1 = threading.Thread(target=server.executeDownload, args=())
    t2 = threading.Thread(target=server.liveDownloadStats, args=())
    t1.start()
    t2.start()

if __name__ == "__main__":
    Main()

关于Python:启动类方法时线程不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27031899/

相关文章:

python - 打印格式合理的列表

python - 检查一个词是否存在于字典中没有找到任何词

java - 使用线程输入

c++ - UML 类图(操作隔间)

java - Java中接口(interface)和实现类的用法区别

c++ - 构造函数的多重定义

Python 随机音频

python - 属性错误 : 'PathCollection' object has no property 'markeredgecolor'

java - 在多个线程之间共享对象

windows - 什么是装载机锁?