在一个函数中,我想每 2 秒调用一次。每当我使用睡眠功能时,代码会等待 2 秒然后转到下一条指令。但是,我想在不干扰其他指令的情况下每 2 秒调用一次函数。例子;
a = None
def foo():
    bar()
    a = a * 12 
    print "A : ",a
def bar():
    a = 0
每两秒,a 应该被重置。但是,在两秒钟内 a 的值应该增加并显示。可能吗 ?如何 ?
在一个函数中,我想每 2 秒调用一次。每当我使用睡眠功能时,代码会等待 2 秒然后转到下一条指令。但是,我想在不干扰其他指令的情况下每 2 秒调用一次函数。例子;
a = None
def foo():
    bar()
    a = a * 12 
    print "A : ",a
def bar():
    a = 0
每两秒,a 应该被重置。但是,在两秒钟内 a 的值应该增加并显示。可能吗 ?如何 ?
You could poll for the time. That is read the current time, store it, process your stuff and then busy wait till the current time matches the stored time + 2 seconds. If you want to you can add a sleep after your stuff. But make sure that the sleep will be finished before the 2 seconds intervall has passed. E.g. sleep for only 1.5 seconds.
If you want to run it independently then you will need to use threading. http://docs.python.org/2/library/threading.html
You may also want to consider the answers here: Executing periodic actions in Python
import time, threading
def foo():
    print(time.ctime())
    threading.Timer(10, foo).start()
use threading.Timer. but just running bar in your code in separate timer won't work, you have to think about using variables between threads first.
我会使用线程和锁来满足您的需求。
事实上,我喜欢我的朋友 Pepe 编写的开源 ThreadPool。
这是 ThreadPool 代码,然后是一个可能的解决方案:
#! /usr/bin/python
# -*- coding: utf-8 -*-
# File: threadPool.py
import threading
import Queue
import time
import sys
import traceback
import datetime
Instance = None
def getInstance():
    global Instance
    if not Instance:
        Instance = ThreadPool()
    return Instance
class ThreadPool:
    def __init__(self,maxWorkers = 10):
        self.tasks = Queue.Queue()
        self.workers = 0
        self.working = 0
        self.maxWorkers = maxWorkers
        self.allKilled = threading.Event()
        self.countLock = threading.RLock()
        self.timers = {}
        self.timersLock = threading.Lock()
        self.timersThreadLock = threading.Lock()
        self.timersEvent = threading.Event()
        self.allKilled.set()
    def run(self,target,callback = None, *args, **kargs):
        """ starts task.
            target = callable to run with *args and **kargs arguments.
            callback = callable executed when target ends
                       callback sould accept one parameter where target's
                       return value is passed.
                       If callback is None it's ignored.
        """
        self.countLock.acquire()
        if not self.workers:
            self.addWorker()
        self.countLock.release()
        self.tasks.put((target,callback,args,kargs))
    def setMaxWorkers(self,num):
        """ Sets the maximum workers to create.
            num = max workers
                  If number passed is lower than active workers 
                  it will kill workers to match that number. 
        """
        self.countLock.acquire()
        self.maxWorkers = num
        if self.workers > self.maxWorkers:
            self.killWorker(self.workers - self.maxWorkers)
        self.countLock.release()
    def addWorker(self,num = 1):
        """ Add workers.
            num = number of workers to create/add.
        """
        for x in xrange(num):
            self.countLock.acquire()
            self.workers += 1
            self.allKilled.clear()
            self.countLock.release()        
            t = threading.Thread(target = self.__workerThread)
            t.setDaemon(True)
            t.start()
    def killWorker(self,num = 1):
        """ Kill workers.
            num = number of workers to kill.
        """
        self.countLock.acquire()
        if num > self.workers:
            num = self.workers
        self.countLock.release()
        for x in xrange(num):
            self.tasks.put("exit")            
    def killAllWorkers(self,wait = None):
        """ Kill all active workers.
            wait = seconds to wait until last worker ends
                   if None it waits forever.
        """
        self.countLock.acquire()
        self.killWorker(self.workers)
        self.countLock.release()
        self.allKilled.wait(wait)
    def __workerThread(self):
        while True:
            task = self.tasks.get()
            # exit is "special" tasks to kill thread
            if task == "exit":
                break
            self.countLock.acquire()
            self.working += 1
            if (self.working >= self.workers) and (self.workers < self.maxWorkers): # create thread on demand
                self.addWorker()
            self.countLock.release()
            fun,cb,args,kargs = task
            try:
                ret = fun(*args,**kargs)
                if cb:
                    cb(ret)
            except:
                ty,val,tb = sys.exc_info()
                print "Thread Catch:%s" % "".join(traceback.format_exception(ty,val,tb))
            self.countLock.acquire()
            self.working -= 1
            self.countLock.release()                
            del(fun) # Dereference all
            del(cb)
            del(args)
            del(kargs)
            del(task)
        self.countLock.acquire()
        self.workers -= 1
        if not self.workers:
            self.allKilled.set()
        self.countLock.release()
    def timer(self, cb, period):
        """ Add or remove timers.
            cb = callback function.
            period = period in seconds (float)
                     if period is 0 timer is deleted.
        """ 
        self.run(self.__timerThread, None, cb, period) 
    def __timerThread(self, cb, period):
        self.timersLock.acquire()
        self.timersEvent.set()
        if not period:
            if cb in self.timers:
                del(self.timers[cb])
            self.timersLock.release()
            return
        self.timers[cb] = [period,time.time()]    
        self.timersLock.release()
        if not self.timersThreadLock.acquire(0):
            return
        while True:
            self.timersLock.acquire()
            if len(self.timers) == 0:
                self.timersThreadLock.release()
                self.timersLock.release()
                break
            minWait = 30*24*3600
            now = time.time()
            for k,v in self.timers.items():
                period, last = v
                wait = period - (now - last)
                if wait <=0:
                    self.run(k)
                    wait = period
                    v[1] = now
                if wait < minWait:
                    minWait = wait
            self.timersLock.release()
            self.timersEvent.wait(minWait)
            self.timersEvent.clear()         
和一个可能的解决方案:
#! /usr/bin/python
# -*- coding: utf-8 -*-
# File: a.py
import threadPool
import time
import threading
class A:
    def __init__(self):
        self.a = 1
        self.alock = threading.Lock()
        self.tp = threadPool.getInstance()
    def bar(self):
        self.alock.acquire()
        self.a = 1
        self.alock.release()
    def foo(self):
        self.tp.timer(self.bar, 2)
        while True:
            self.alock.acquire()
            self.a = self.a * 12 
            self.alock.release()
            print "A : ",self.a
            time.sleep(0.1)
a = A()
a.foo()
跑:
$ python a.py