每个类中的局部变量 - python定时循环

时间:2013-02-15 00:08:35

标签: python

我有一个连续循环读取外部文件的python文件,我有很多不同的数据点我正在阅读并有一个类(fb),我打电话来提供每个点的位置( m1.x,m2.x等....)文件每30秒循环一次。

我需要一个循环中的变量,它不会为我正在使用的每个实例重置。如果我在循环中定义它,它将被重置,如果我使用全局变量,我不能将它用于多个变量。

因此,在下面的示例中,'test'对所有实例计为1,因为它是一个全局变量,self.X在每个循环后重置。这些都不是我需要的。我试图使用线程,但这会导致我正在使用的模块出现更多问题。因此,如果有人对如何创建一个局部变量有任何想法,而该局部变量未在一个循环的类中重置,那将是很好的。谢谢。

test = 0  
s = sched.scheduler(time.time, time.sleep)

def loop1(sc): 
    class fb:
        def link(self):
            global test
            test = test + 1
            print test

            self.X = self.X + 1
            print self.X

    m1 = fb()

    m1.X = 1
    m1.link()

    m2 =fb()
    m2.X = 0
    m2.link()

    # Update loop every 10 second    
    sc.enter(10, 10, loop1, (sc,))


# end loop
s.enter(1, 1, loop1, (s,))
s.run()

3 个答案:

答案 0 :(得分:1)

您无法创建每次都不重置的局部变量。局部变量的重点是它是本地的。所以,它不能是局部变量。

但它也不能是一个全局变量,因为你希望能够有两个不同的预定loop1函数,而不是同一个变量。

所以,你需要做的是重新组织事物,以便循环实例本身就是一个东西,可以有一个绑定到它的变量。有两种基本方法可以做到这一点。

首先,有传统的OO解决方案,即创建一个类,并使您的函数成为一个实例方法,然后可以访问实例变量。像这样:

class Looper(object):
    def __init__(self):
        self.test = 0
    def loop1(self, sc):
        # same code as before, but with self.test instead of test

looper1 = Looper()
looper2 = Looper()
s.enter(1, 1, looper1.loop1, (s,))
s.enter(1, 1, looper2.loop1, (s,))

或者,有传统的FP创建闭包的解决方案:

def make_loop1():
    test = 0
    def loop1(sc):
        nonlocal test
        # same code as before, unchanged
    return loop1
looper1 = make_loop1()
looper2 = make_loop1()
s.enter(1, 1, looper1, (s,))
s.enter(1, 1, looper2, (s,))

然后有各种混合解决方案,您将函数本身视为OO对象(例如,将test指定为函数的属性),或通过传递可变值作为参数伪造闭包等等。

答案 1 :(得分:1)

我认为你想要一个对象 y 来计算循环的次数,而不是每个回合中创建的实例数(= self.X),也不是自从创建以来创建的累积实例数。程序开始(=测试)

我已经获得了以下程序来获取对象 y ,该对象仅在循环的每个回合处递增1。它需要在转弯开始时创建一个全新的类。指令

fb = type('fb',(object,),{'__init__':initer,
                              'link':linker,
                              'CLASSIES':0})

创建一个全新的类。通过显示创建的类来证明:print 'id(fb) == %d' % id(fb)
对象的身份是它在内存中的位置。如果它不是同一个id,则它不是同一个对象:

import sched,time

test = 0  
s = sched.scheduler(time.time, time.sleep)

Y = 2000

def initer(self):
    global test,Y
    if self.__class__.CLASSIES == 0:
        Y += 1
        self.__class__.CLASSIES += 1

def linker(self):
    global test,Y
    test = test + 1
    self.X = self.X + 1
    print 'Y == %d' % Y
    print 'test == %d     self.X == %d' % (test,self.X)


def loop1(sc):
    fb = type('fb',(object,),{'__init__':initer,
                              'link':linker,
                              'CLASSIES':0})
    print '--------'
    print 'id(fb) == %d' % id(fb)
    m1 = fb()
    m1.X = 0
    m1.link()
    print 
    m2 =fb()
    m2.X = 1
    m2.link()
    print 
    m3 =fb()
    m3.X = 2
    m3.link()
    print '--------'

    # Update loop every 10 second
    sc.enter(10, 10, loop1, (sc,))


# end loop
s.enter(1, 1, loop1, (s,))
s.run()

显示器

--------
id(fb) == 18976648
Y == 2001
test == 1     self.X == 1

Y == 2001
test == 2     self.X == 2

Y == 2001
test == 3     self.X == 3
--------
--------
id(fb) == 13818640
Y == 2002
test == 4     self.X == 1

Y == 2002
test == 5     self.X == 2

Y == 2002
test == 6     self.X == 3
--------
--------
id(fb) == 18970384
Y == 2003
test == 7     self.X == 1

Y == 2003
test == 8     self.X == 2

Y == 2003
test == 9     self.X == 3
--------
--------
id(fb) == 18970864
Y == 2004
test == 10     self.X == 1

Y == 2004
test == 11     self.X == 2

Y == 2004
test == 12     self.X == 3
--------
--------
id(fb) == 18971736
Y == 2005
test == 13     self.X == 1

Y == 2005
test == 14     self.X == 2

Y == 2005
test == 15     self.X == 3
--------
--------
id(fb) == 18957224
Y == 2006
test == 16     self.X == 1

Y == 2006
test == 17     self.X == 2

Y == 2006
test == 18     self.X == 3
--------
.
.
.
etc

我只能通过上述方式获得这个结果 在每个回合结束时删除fb是不够的,因为您将看到是否运行以下代码。这是您的代码,其中包含更多说明,Yid(fb)的显示。你会看到`` an id(fb)``从一个回合到另一回合保持不变。

import sched,time

test = 0  
s = sched.scheduler(time.time, time.sleep)

Y = 2000

def loop1(sc):
    class fb:
        def link(self):
            global test,Y
            test = test + 1
            self.X = self.X + 1
            print 'Y == %d' % Y
            print 'test == %d     self.X == %d' % (test,self.X)
    print 'id(fb) == %d' % id(fb)
    print '--------'
    m1 = fb()
    m1.X = 0
    m1.link()
    print 
    m2 =fb()
    m2.X = 1
    m2.link()
    print 
    m3 =fb()
    m3.X = 0
    m3.link()
    print '--------'
    del fb

    # Update loop every 10 second
    sc.enter(10, 10, loop1, (sc,))


# end loop
s.enter(1, 1, loop1, (s,))
s.run()

你的代码没有按照你的意愿工作的原因,我真正理解你想要的是,定义类的脚本部分被称为"类的定义&# 34; (不可思议,不是吗?)当解释器第一次传递这个类块时,执行它。
执行"类定义"创建一个类的对象。一旦创建了类,"定义"如果口译员再次通过课程,则不会重新执行。代码块(=类定义)。
在这里,有一个含糊不清的词:'定义'可以理解为脚本中定义一个类'的文本块。或者作为执行定义类的创建并导致对象成为类的指令的过程'
我用于"类的定义"是文档中使用的那个:

  

类定义,如函数定义(def语句)必须是   在它们产生任何影响之前执行。 (你可以想象一下   在if语句的分支中或在a中的类定义   功能。)

     

http://docs.python.org/2/tutorial/classes.html#class-definition-syntax

所以,最后,我想说的是,在你的代码中,fb"类的定义是"只执行一次,然后它总是与建模类相同的类,在循环之后转动。

答案 2 :(得分:-1)

之前我已经完成了这个...制作一个模块,或者如果你对此感到满意,可能只是使用__ init__.py

在__ init__.py或wherever.py

from somepackage.some_module import my_function
my_obj = my_function()

在your_awesome_module.py中,您可以使用对象

from path.to.wherever import my_obj
# Do stuff with my_obj