Python - 在基于属性更改的方法中停止while循环

时间:2016-10-20 18:29:37

标签: python loops oop

我有一个非常简单的类,有一个属性和一个方法。我希望该方法基于属性的值运行。下面是班级代码:

class TestWhile()
   def __init__(self):
      self.status = "OFF"
   def StreamV(self):
      while self.Status == "ON"
         print "nonstop"

基本上我要做的是将Status设置为ON,然后运行StreamV直到Status设置为off。这就是我想要的如下:

P = TestWhile()
T.Status = "ON"
T.StreamV()
T.Status = "OFF"

当我运行上述测试时,它永远不会进入Status =" OFF" line并无限运行循环。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

your call to T.StreamV() does what is commonly referred to as Busy looping and blocks the main thread. What you have effectively described you want is a background thread to update some value until a signal comes in (from your T.Status attribute)

Threading is relatively approachable for simple problems, and is an incredibly useful tool to get to know. From a super wide viewpoint a thread in python is a function that can run at the same time the main script is doing something else. In this regard python threads are indeed created by passing them a function to execute.

Example:

import threading
import time

class TestWhile(object):
    def __init__(self):
        self.status = "OFF"
        self.streamVthread = threading.Thread(target=self.StreamV) #create a thread for our streamV function
    def StreamV(self):
        print "starting thread"
        while self.Status == "ON":
            print "nonstop"
            time.sleep(1)
        print "stopping thread"

T = TestWhile() #our thread is actually created here, but is hasn't started yet
print 'T.Status -> "ON"'
T.Status = "ON"  #T.StreamV could be modified to run at creation and wait for this to change to "ON"
T.streamVthread.start() #this calls the T.StreamV function in a separate thread
time.sleep(6)
T.Status = "OFF"
print 'T.Status -> "OFF"'

I've added a bunch of print statements to help you understand the flow of the program. Please comment with any questions.

Edit: passing arguments to a thread

Threads exist in the same namespace as the main thread, so if they share a variable with the main script they will both have access to it. This can cause problems with multiple threads accessing the same thing at the same time (read more on locks and other mutex constructs). Passing arguments at creation of the thread however can be done as such:

import threading
import time

def sayHello(after_secs, name):
    time.sleep(after_secs)
    print("hello from {}".format(name))

thread1 = threading.Thread(target=sayHello, args=(3,"thread1"))
thread2 = threading.Thread(target=sayHello, args=(1,"thread2"))
thread3 = threading.Thread(target=sayHello, args=(5,"thread3"))

print "starting thread1"
thread1.start()
print "starting thread2"
thread2.start()
print "starting thread3"
thread3.start()


thread1.join() #wait for thread1 to finish
print "thread1 is done"
thread2.join() #wait for thread2 to finish
print "thread2 is done"
thread3.join() #wait for thread3 to finish
print "thread3 is done"

See if you can determine why these print statements happen in the order they do..