python - 使用线程和类设计的初学者程序

标签 python multithreading class

这个问题似乎太长了,任何人都无法发表评论...我正在尝试在名为“laulau.py”的模块中打印一些文本和进度条。这是一段测试代码,显示了一个简单的版本。我的目标是只有一个线程,并向其发送信息。我的问题是最好的方法是什么?

文件1(测试.py)

#!/usr/bin/env python

from laulau import laulau
import time

print "FIRST WAY"

total=107
t=laulau()
t.echo('this is text')
t.setbartotal(total)
for a in range(1,total):
    t.updatebar(a)
    time.sleep(0.01)
time.sleep(1)
print
print "\ndone loop\n"
t.stop()
time.sleep(1)

print "SECOND WAY"

with laulau().echo("this is text"):
    time.sleep(1)
    print "\nyes this is working\n"
    time.sleep(2)

文件2:laulau.py

#!/usr/bin/env python
# vim:fileencoding=utf8

from __future__ import division
import time
import string
import threading
from sys import stdout


class laulau(threading.Thread):

    def __init__(self, arg=None):
        super(laulau,self).__init__()
        self._stop = False
        self.block='█'
        self.empty='□'
        self.TEMPLATE = ('%(progress)s%(empty)s %(percent)3s%%')
        self.progress = None
        self.percent = 0
        self.bar_width=30
        self.bartotal=None

    def run (self):
        # start thread for text
        while not self._stop:
            if self.bartotal is None:
                print self.arg,
                stdout.flush()
                time.sleep(0.3)
            else:
                self.progress = int((self.bar_width * self.percent) / 100)
                self.data = self.TEMPLATE % {
                        'percent': self.percent,
                        'progress': self.block * self.progress,
                        'empty': self.empty * (self.bar_width - self.progress),
                }

                stdout.write('\033[%dG'%1 + self.data + self.arg)
                stdout.flush()
                time.sleep(0.1)

    def setbartotal(self,total):
        # set progress bar total
        if self.bartotal is None:
            self.bartotal = total
            self.updatebar(0)

    def updatebar (self,num):
        self.num=num
        self.percent = self.percentage(self.num)

    def percentage (self,numagain):
        return int((numagain/self.bartotal)*100+1)

    def echo (self,arg="Default"):
        #self.thread_debug()
        self.arg=arg
        self._stop = False
        self.start()
        return self

    def thread_debug(self):
        print "threading enumerate :%s"%threading.enumerate()
        print "current thread :%s"%threading.currentThread()
        print "thread count (including main thread):%s"%threading.activeCount() 

    def stop(self):
        self._stop = True

    def stopped(self):
        return self._stop == True

    def __enter__(self):
        print "\nwe have come through the enter function\n"
        return self

    def __exit__(self, type, value, traceback):
        self._stop = True
        print "\nwe have exited through the exit function\n"
        return isinstance(value, TypeError)

在某些情况下,第二种方法可能有效。例如,当我打印一些文本时,只需要线程在其末尾终止,但在进度条需要向其发送更新时则不需要。虽然这一切都很有效,而且我学到了很多东西,但我仍然不知道如何以我想要的方式封装这个类。因为我只想要一个线程,所以我实际上不需要继续实例化该类,我只需要执行一次。

所以例如我理想的方法是只具有三个功能:

  • 1 控制文本、打开进度条等(从一个已解析的字符串中)
  • 2 设置进度条总计
  • 3 设置进度条迭代

我需要更改类中的两个变量(用于进度条)

  • 总共一个
  • 一个用于迭代

...并从中计算出百分比。

首先,我认为我应该通过从线程继承类内容来启动线程,然后在查看 threading.Thread(target=blah,etc) 后,我一开始不知道如何使用不止一个函数,然后我发现我可以将类名放入其中 threading.Thread(target=laulau) ,这样就会启动一个包含该类的线程,但后来我对如何实现这一点感到困惑发送该线程信息,因为我没有将其分配给“名称”,如 t=laulau()

我的第二个想法是在我的模块中拥有类之外的函数,但是因为我需要多个函数,所以通过将其添加到 laulau.py 的开头,我也感到有点困惑:

def eko (arg):
    t=laulau()  
    t.echo(arg)

def barupate(iteration):
    t.updatebar(a)

def bartotal():
    t.setbartotal(a)

第一个函数创建了该类的实例,但前面的函数无法更改其中的任何变量。然后我遇到了诸如 this 之类的函数属性。

class Foo:
    @webmethod
    def bar(self, arg1, arg2):
         ...

def webmethod(func):
    func.is_webmethod = True
    return func

然后我开始思考也许我可以以某种方式使用它,但以前从未遇到过它。

理想情况下,像这样:

echo.total(107)
echo('[progressbar] this is text') # starts progress bar and instance of thread if not already there...
for a in range(1,total):
    echo.updatebar(a)
    time.sleep(0.01)
    time.sleep(1)
    echo.stop() # bar would stop at the end of iterations but text animations (blinking etc) may still be going at this point...
    print
    print "\ndone loop\n"

如果你了解 python,你现在可能会觉得我很有趣,但请记住,我是一个完全的非专业初学者,每天都在学习,这很大程度上要归功于这个网站。为任何帮助干杯!

编辑:应该补充一点,我知道进度条模块和各种其他食谱,但我这样做是为了学习和娱乐目的:)

最佳答案

如果您只需要打印进度条,请使用 sys 模块,如下所示:

import sys
import time

progress = "0"                                 #this is an int meant to represent 0-100 percent as 0-100
old = "0"                                      #this represents the last updates progress, so that this update only adds the difference and not the full progress

def updatebar(progress,old):
    for item in range((progress-old)/2)        #this takes the range of progress but divides it by 2, making the progress bar 50 characters long
    sys.stdout.write("-")                      #to change the character used to fill the progress bar change the "-" to something else
    sys.stdout.flush()

#you may not want to use a while loop here, this just has an example of how to use the update function as it adds one to the progress bar every second
while True:
    progress += 1
    updatebar(progress,old)
    old = progress                             #sets the old progress as the current one, because next iteration of the while loop the previous progress will be this one's current progress.
    time.sleep(1)

关于python - 使用线程和类设计的初学者程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8486044/

相关文章:

python - Postgresql 启动失败

python - python中的出列函数

c# - 将 WPF 控件类作为模板类

java - 找不到主类运行jar

python - 为什么 TensorFlow WHL 文件不包含所有必需的依赖项?

python - py-appscript 和事件

python - Pandas 数据框在列中舍入值

java - 我的代码中有一个第三方异步 block 。我怎么知道它什么时候结束?

c# - 是否使用线程从网络下载文件

C++ 重载运算符 << 让我做噩梦