我有一个python文件,它处于从外部文件读取的连续循环中,我正在读取许多不同的数据点,并且我正在调用一个类(fb)来提供每个点的位置(m1.x、m2.x等…)文件每30秒循环一次。
我在循环中需要一个变量,它不会为我使用的每个实例重置。如果我在循环中定义它,它会被重置,如果我使用全局变量,我不能将其用于多个变量。
因此,在下面的例子中,"test"作为全局变量和self,对所有实例都按1计数。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()
我认为您想要一个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)
的显示。您将看到`` 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()
据我所知,你的代码不能按你想要的方式工作的原因是,脚本中定义类的部分被称为"类的定义"(不可思议,不是吗?),当解释器第一次传递这个类块时,它执行它。
执行"类的定义"会创建一个作为类的对象。一旦创建了类,如果解释器再次传递类的代码块(=类定义),则不会重新执行"定义"
这里还有一个模棱两可的词:"定义"可以理解为"定义类的脚本中的文本块"或"执行定义类的创建并导致对象成为类的指令的过程"
我用于"类的定义"的含义是文档中使用的含义:
类定义,如函数定义(def语句),必须是在生效之前执行。(你可以想象if语句分支中的类定义,或函数。)
http://docs.python.org/2/tutorial/classes.html#class-定义语法
最后,我想说的是,在你的代码中,"类fb的定义"只执行一次,然后总是同一个类在建模类,循环一个接一个。
不能创建每次都不重置的局部变量。局部变量的全部意义在于它是局部的。所以,它不可能是局部变量。
但它也不能是全局变量,因为您希望能够拥有两个不同的调度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
指定为函数的属性),或者通过传递可变值作为参数来伪造闭包,等等。
我以前做过。。。制作一个模块,或者如果你对很满意,可以只使用__init__.py
在__ init__.py或where ver.py 中
from somepackage.some_module import my_function
my_obj = my_function()
在您的_awesome_module.py中,您可以使用您的对象
from path.to.wherever import my_obj
# Do stuff with my_obj