如何定期将项目插入到另一个 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) 你几乎肯定不需要线程。
根据您的编程知识水平,我猜您实际上不需要线程来完成您的任务。大多数情况下,程序员应该避免使用显式线程,直到绝对无法避免为止。
我在从另一个 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) 你几乎肯定不需要线程。
根据您的编程知识水平,我猜您实际上不需要线程来完成您的任务。大多数情况下,程序员应该避免使用显式线程,直到绝对无法避免为止。