我遇到了一个我无法解决的问题,它与多处理相关联,并在装饰器中使用。
当我使用多进程调用方法run_in_parallels时,我得到的是错误:
Can't pickle <function run_testcase at 0x00000000027789C8>: it's not found as __main__.run_testcase
调用发生在装饰器内部,然后遵循上述问题.在调用相同方法时,没有装饰器的run_in_parallels都正常工作。
这个问题的原因是什么?
文件: w_PythonHelper.py
desc:函数'run_in_parallel‘用于同时运行多个进程。第一种方法将结束操作,停止其他操作。
from multiprocessing import Process,Event
class ExtProcess(Process):
def __init__(self, event,*args,**kwargs):
self.event=event
Process.__init__(self,*args,**kwargs)
def run(self):
Process.run(self)
self.event.set()
class PythonHelper(object):
@staticmethod
def run_in_parallel(*functions):
event=Event()
processes=dict()
for function in functions:
fname=function[0]
try:fargs=function[1]
except:fargs=list()
try:fproc=function[2]
except:fproc=1
for i in range(fproc):
process=ExtProcess(event,target=fname,args=fargs)
process.start()
processes[process.pid]=process
event.wait()
for process in processes.values():
process.terminate()
for process in processes.values():
process.join()文件: w_Recorder.py
desc:函数“捕获”用于抓取屏幕截图
from PIL import ImageGrab
import time
class Recorder(object):
def capture(self):
ImageGrab.grab().save("{f}.{e}".format(f=time.time(),e="png"))文件: w_Decorators.py
desc:并行运行给定函数的以及类“Recorder”的“捕获”方法
from w_Recorder import Recorder
from w_PythonHelper import PythonHelper
def check(function):
def wrapper(*args):
try:
recorder=Recorder()
PythonHelper.run_in_parallel([function,args],[recorder.capture])
print("success")
except Exception as e:
print("failure: {}".format(e))
return function
return wrapper文件: w_Logger.py
desc:主程序(生成错误)
from w_Decorators import check
import time
class Logger(object):
@check
def run_testcase(self):
# example function (runtime: 20s)
for i in range(20):
print("number: {}".format(i))
time.sleep(1)
def run_logger(self):
self.run_testcase()
if __name__=="__main__":
logger=Logger()
logger.run_logger()文件: w_Logger.py
desc:主程序(同步工作)
from w_PythonHelper import PythonHelper
from w_Recorder import Recorder
import time
class Logger(object):
def run_testcase(self):
# example function (runtime: 20s)
for i in range(20):
print("number: {}".format(i))
time.sleep(1)
def run_logger(self):
recorder=Recorder()
PythonHelper.run_in_parallel([self.run_testcase],[recorder.capture])
if __name__=="__main__":
logger=Logger()
logger.run_logger()在这两种情况下,这些相同的方法有什么不同呢?
编辑:有没有人有解决这个问题的想法(这是Python错误吗?)如果没有,也许有人知道在应用程序运行时捕捉屏幕截图的好方法?
事实上,我发现了类似的问题:multiprocessing.Process子类在Linux上工作,而不是Windows。
答案是:To fix this, you can remove the process member.,但我如何才能对我的例子做到这一点。
调试时,在run_in_parallel(*functions)中调用run_in_parallel(*functions)时会发生错误
ivan_pozdeev写道:我可以使用包装器作为函数,但不能使用它作为装饰器。我有许多功能装饰由这个装饰和最简单的方式是使用多处理内部装饰。但不幸的是我解决不了这个问题。也许有人已经解决了类似的问题。如有任何提示,我将不胜感激。
'run_in_parallel'函数按照我的要求工作。两个或多个函数并行运行,第一个函数完成后强制终止第二个函数。当我调用包装器(,*args)时,函数工作正常,当我在装饰器中放置这个机制时,我得到了‘无法选择函数……它不是“错误”。详情见上文。
我的回溯:
Traceback (most recent call last):
File "C:\Interpreters\Python32\lib\pickle.py", line 679, in save_global
klass = getattr(mod, name)
AttributeError: 'module' object has no attribute 'run_testcase'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\EskyTests\w_Logger.py", line 19, in <module>
logger.run_logger()
File "C:\EskyTests\w_Logger.py", line 14, in run_logger
self.run_testcase()
File "C:\EskyTests\w_Decorators.py", line 14, in wrapper
PythonHelper.run_in_parallel([function,args],[recorder.capture])
File "C:\EskyTests\w_PythonHelper.py", line 25, in run_in_parallel
process.start()
File "C:\Interpreters\Python32\lib\multiprocessing\process.py", line 130, in start
self._popen = Popen(self)
File "C:\Interpreters\Python32\lib\multiprocessing\forking.py", line 267, in __init__
dump(process_obj, to_child, HIGHEST_PROTOCOL)
File "C:\Interpreters\Python32\lib\multiprocessing\forking.py", line 190, in dump
ForkingPickler(file, protocol).dump(obj)
File "C:\Interpreters\Python32\lib\pickle.py", line 237, in dump
self.save(obj)
File "C:\Interpreters\Python32\lib\pickle.py", line 344, in save
self.save_reduce(obj=obj, *rv)
File "C:\Interpreters\Python32\lib\pickle.py", line 432, in save_reduce
save(state)
File "C:\Interpreters\Python32\lib\pickle.py", line 299, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Interpreters\Python32\lib\pickle.py", line 623, in save_dict
self._batch_setitems(obj.items())
File "C:\Interpreters\Python32\lib\pickle.py", line 656, in _batch_setitems
save(v)
File "C:\Interpreters\Python32\lib\pickle.py", line 299, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Interpreters\Python32\lib\pickle.py", line 683, in save_global
(obj, module, name))
_pickle.PicklingError: Can't pickle <function run_testcase at 0x00000000027725C8>: it's not found as __main__.run_testcase发布于 2011-11-14 20:11:55
很棘手,但我认为所发生的事情是,在定义类时,check存储对未绑定方法的引用。工作示例在调用self.run_testcase时使用对绑定方法run_logger的引用。
我认为最好的办法是让run_testcase成为顶级函数,而不是类的方法。
而且,您的capture函数可能不会按照您的预期完成--在定义函数时将存储当前时间,并且每个屏幕截图都将保存在前面的屏幕截图中。您可能希望在函数中调用time.time()。
https://stackoverflow.com/questions/8126654
复制相似问题