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

How to insert items periodically to the List of another python script?

我在从另一个 Python 脚本文件更新列表 L[] 的项目时遇到问题。 以下是我现在拥有的两个简单文件,任何 help/suggestion/advise 将不胜感激。

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 的所有 运行 function/s!?

非常感谢,

根据建议编辑之前的代码后,现在我有以下脚本:

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 列表中。有什么建议么?

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

你想做的是在这里使用 class。

class ListHolder: 
      self.L=[] 

然后您就可以毫无问题地访问ListHolder.L。总之 运行 你不想使用全局变量,所以 python 鼓励你在这里做正确的事。

如果您认为自己的代码是独立的,并且应该放在自己的文件中,那么 class 或模块通常是 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 ...' 

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

不是这样!

需要考虑的几点:

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

这不会导致并行执行,并且脚本不会相互独立运行。您只是让出脚本之间的控制权。线程最适合异步操作——它不会导致并行执行或独立状态。考虑事件处理程序和回调等情况。

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

Python 不是并行编程的好选择。您可以使用 "Process" class 来启动独立进程,然后在外部管理它们。但是,"Process" 不理解进程是 Python 程序,您无法直接影响它们的变量。这样做的方法是 运行 小流程,return 值供中央流程推理。想想 OpenGL 着色器。

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

无法保证线程的执行时间。您的原始脚本有时可能有效,而其他时候无效。您需要使用 locks/mutexes 来防止数据竞争。如果您真的打算使用线程,则需要认真考虑如何保护数据免受数据争用。如果你需要帮助,你应该开始一个新的问题。

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

根据您的编程知识水平,我猜您实际上不需要线程来完成您的任务。大多数情况下,程序员应该避免使用显式线程,直到绝对无法避免为止。