0

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

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

因此,在下面的示例中,'test' 将所有实例作为全局变量计数,并且 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()
4

3 回答 3

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作为函数的属性进行赋值),或者通过将可变值作为参数传递来伪造闭包等。

于 2013-02-15T00:27:13.367 回答
1

我认为您想要一个对象y来计算循环的轮数,而不是每轮创建的实例数(= self.X),也不是自程序启动以来创建的实例的累积数(= test)

我有以下程序来获取仅在循环的每一圈递增一的对象y 。它需要在回合开始时创建一个全新的类。该指令

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是不够的,因为您将看到是否运行以下代码。它是您的代码,带有更多指令,具有Y和显示id(fb). 你会看到`` anid(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()

据我所知,您的代码无法按您的意愿工作的原因是定义类的脚本部分称为“类的定义”(难以置信,不是吗? ) 并且当解释器第一次传递这个类块时,它会执行它。
“类定义”的执行创建了一个类对象。创建类后,如果解释器再次通过类的代码块(= 类定义),则不会重新执行“定义”。
这里又出现了一个模棱两可的词:“定义”可以理解为“脚本中定义类的文本块”或“
我用于“类定义”的含义是文档中使用的含义:

类定义,如函数定义(def 语句)必须在它们生效之前执行。(您可以想象将类定义放在 if 语句的分支或函数内。)

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

所以,最后,我想说的是,在你的代码中,“fb 类的定义”只执行一次,然后总是同一个类是建模类,一个接一个地循环。

于 2013-02-15T02:03:02.973 回答
-1

我以前做过这个......制作一个模块,或者如果你觉得舒服的话,也许只是使用 __ init__.py

在 __init__.py 或 where.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
于 2013-02-15T00:31:30.080 回答