如何定期将项目插入另一个python脚本的列表?

时间:2017-10-27 13:30:30

标签: python python-2.7 ipc message-passing

我在从另一个Python脚本文件更新List L []的项目时遇到问题。 下面是我现在拥有的两个简单文件,任何帮助/建议/建议都将受到高度赞赏。

script1.py

import time, threading
L=[]
def first():
    if len(L)!=0:
       x = L.pop()
       print 'The element', x, 'left the list L'
    else:
         print 'L is empty now ...'
    threading.Timer(10, first).start()

first() 

script2.py

from __main__ import *
import time
import script1
c = 1
def pass_arg():
    global c
    c+=1
    L.append(c)
    print 'will pass value to the list L of script1.py'
    threading.Timer(10, pass_arg).start()

pass_arg()

我面临的问题是sript2无法访问script1的已定义列表L.此外,script2开始遵循script1的所有运行函数!?

非常感谢,

根据建议编辑上一代码后,现在我有以下脚本:

script1.py

from __main__ import *
import time, threading

class ListHolder: 
  def __init__(self):
    self.L = [] 

  def first(self):
    if len(self.L)!=0:
       x = self.L .pop()
       print 'The element', x ,'left the list L'
    else:
        print 'L is empty now ...'
    threading.Timer(10, self.first).start()

R = ListHolder()
R.first()

script2.py

from __main__ import *
import time, threading
from script1 import ListHolder

c = 1

X = ListHolder()

def pass_arg():
    global c
    c+=1
    X.L.append(c)
    print X.L
    print 'will pass value to the list L of script1.py'
    threading.Timer(10, pass_arg).start()

pass_arg()

现在的主要问题是script2.py新添加的项目没有传递给script1.py,因此script1.py中的List始终为空,并且更改未反映在script1列表中。有什么建议?

1 个答案:

答案 0 :(得分:3)

Python没有真正的全局变量,或者至少它们不像你使用它们那样工作。对于它有什么价值,Stack Overflow上有很多其他答案,例如Using global variables in a function other than the one that created them,它们的答案详细说明了如何绕过默认行为,但它有点hacky而不是真的在大多数情况下Python希望你做什么。

你想要做的是在这里使用一堂课。

class ListHolder: 
      self.L=[] 

然后你就可以访问ListHolder.L而不会有任何麻烦。从长远来看,你不想使用全局变量,所以python鼓励你在这里做正确的事。

如果您认为自己拥有自包含的代码,并且该代码应该包含在自己的文件中,那么类或模块通常是Python中的正确选择。

更新以响应OP的更新: 首先,让我们逐行浏览您的脚本并做一些评论。

我们将从script2.py

开始
from __main__ import * #Don't need this. 
import time, threading #We don't need threads to do this. 
from script1 import ListHolder #This EXECUTES code in script1.py 

c = 1 #fine

X = ListHolder() #Good 

def pass_arg():
    global c #not necessary 
    c+=1 #fine 
    X.L.append(c) #fine
    print X.L #fine 
    print 'will pass value to the list L of script1.py' #You already did that. 
    threading.Timer(10, pass_arg).start() #You don't need this. 
                                          #furthermore it will execute forever and
                                          #die when it blows the stack. 

pass_arg()  #this is fine 

这是Script2.py

from __main__ import * #this is not needed. 
import time, threading #We aren't using threads. Why import threads? 

class ListHolder: 
  def __init__(self):
    self.L = [] #This should be ok, but we could have also have initialized this 
                #in class scope rather than init. 

  def first(self):
    if len(self.L)!=0: 
       x = self.L .pop()
       print 'The element', x ,'left the list L'
    else:
        print 'L is empty now ...'
    threading.Timer(10, self.first).start() #This will execute forever. 

R = ListHolder() #as these are in "file" scope
R.first()  #they will execute when imported! 

因此,让我们将其简化为更好的格式。

Script2b.py
from script1b import ListHolder 

c = 1 #fine

X = ListHolder() #Good 

def pass_arg(z): #Functions need arguments. 
    z+=1 #we should use function scope vars 
         #instead of mutating global scope. 
    X.L.append(c) #fine
    print X.L #fine 
    return z #return locally mutated data
             #instead of mutating global scope. 

for x in range(1,10):
  c = pass_arg(c)  #this is fine 

  X.popMe()   

script1b.py

class ListHolder: 
  def __init__(self):
    self.L = [] #This should be ok, but we could have also have initialized this 
                #in class scope rather than init. 

  def popMe(self):
    if len(self.L)!=0: 
       x = self.L .pop()
       print 'The element', x ,'left the list L'
    else:
        print 'L is empty now ...' 

既然你一直在尝试使用线程,我怀疑你正在尝试做一些与帖子说的有点不同的事情。我怀疑您的印象是您可以同时运行两个脚本 并使用线程界面在两个脚本之间进行通信。

不是这样!

要考虑几点:

1)您已经编写了一个带线程的脚本。

这不会导致并行执行,并且脚本将不会彼此独立地运行。您只是在脚本之间产生控制权。线程最适合异步操作 - 它不会导致并行执行或独立状态。考虑事件处理程序和回调等情况。

2)Python本身并不支持Parallelism Pe Se:

Python并不是并行编程的绝佳选择。您可以使用"流程"开始独立进程的类,然后在外部管理它们。然而,"过程"不了解这些过程是Python程序,你不能直接影响他们的变量。执行此操作的方法是运行小进程,并返回中央进程的值以进行推理。想想OpenGL着色器。

3)您没有正确管理线程之间的状态。

无法保证线程的执行时间。您的原始脚本有时可能有效,而其他时间则无法运行。您需要使用锁/互斥锁来防止数据争用。如果您真的打算使用线程,则需要仔细考虑如何保护数据与数据集。如果你需要帮助,你应该开始一个关注它的新问题。

4)你几乎肯定不需要线程。

根据您的编程知识水平,我猜您实际上并不需要线程来完成您的任务。程序员大多数时候应该避免使用显式线程,直到绝对不可避免。