2011-12-13 35 views
1

似乎這個問題太長了,任何人都無法評論......我試圖在一個名爲'laulau.py'的模塊中打印出一些文本和一個進度條。這是一段顯示簡單版本的測試代碼。我的目標是隻有一個線程,並向它發送信息。我的問題是這樣做的最好方法是什麼?使用線程和類設計的初學者程序

文件1(test.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 

然後我開始思考,也許我可以用這個方法,但從來沒有遇到過它。

理想ID像這樣的事情:

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" 

如果你知道蟒蛇你可能看着我現在滑稽,但請記住,我是一個總的初學者非專業和正在學習的每這一天,很多感謝這個網站。歡呼任何幫助!

編輯:補充一點,我知道進度條模塊和其他各種食譜,但我做這個學習和娛樂的目的:)

+0

您是否確實需要實現自己的進度條模塊?無論如何,值得一看['python-progressbar'](http://code.google.com/p/python-progressbar/)。 – jcollado

+0

是啊,看到了,不得不把它分開一點......他們不能拼出'一般':)它不僅僅是一個進度條模塊,它還打印文本。我喜歡他們在那裏調用它的方式'pbar = ProgressBar(widgets = widgets)for pbar((我爲我在範圍(24))):' – funk

+0

你說得對,這太長了:)但說,我不明白你爲什麼使用線程來更新和顯示進度條? – sarnold

回答

1

如果你只需要打印出一個進度條,請使用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)