TypeError: can't pickle file objects webpy and subprocess
TypeError: can't pickle file objects webpy and subprocess
我正在尝试使以下代码成为可能。但我不断收到 "TypeError: can't pickle file objects" 错误。我是 python 和 webpy 的新手。谁能告诉我如何实现此代码。
import web
import subprocess
web.config.debug = False
urls = (
"/start", "start",
"/end", "end"
)
app = web.application(urls, locals())
s = web.session.Session(app, web.session.DiskStore('sessions'), initializer={"p": None})
class start:
def GET(self):
s.p = subprocess.Popen(['ls', '-a'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return ""
class end:
def GET(self):
out, err = s.p.communicate();
return out
if __name__ == "__main__":
app.run()
我一直看到的错误是
python27/lib/python2.7/copy_reg.py”,第 70 行,_reduce_ex
引发 TypeError,"can't pickle %s objects" % base.name
类型错误:无法腌制文件对象
我自己是一个网络新手。然而,在做了一些 "research" 之后,似乎 webpy
不能 pickle
subprocess.Popen
对象 [1]。
因此,让我们尝试以下方法——即在 end
响应中创建它并打印其输出。
换句话说:
import web
import subprocess
web.config.debug = False
urls = (
"/start", "start",
"/end", "end"
)
app = web.application(urls, locals())
s = web.session.Session(
app, web.session.DiskStore('sessions'), initializer={"p": None})
class start:
def GET(self):
s.p = ['ls', '-a']
return ""
class end:
def GET(self):
out, err = subprocess.Popen(
s.p , stdout=subprocess.PIPE,
stderr=subprocess.PIPE).communicate()
s.kill() # kill the session.
return out
if __name__ == "__main__":
app.run()
[1] 如您所见:
import pickle
import subprocess
with open('bla', 'wb') as f:
pickle.dump(subprocess.Popen(['ls'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE), f)
subprocess.Popen
returns 一个文件描述符,从回溯中我推断 pickle
无法序列化文件描述符。
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "/usr/lib64/python2.7/pickle.py", line 1370, in dump
Pickler(file, protocol).dump(obj)
File "/usr/lib64/python2.7/pickle.py", line 224, in dump
self.save(obj)
File "/usr/lib64/python2.7/pickle.py", line 331, in save
self.save_reduce(obj=obj, *rv)
File "/usr/lib64/python2.7/pickle.py", line 419, in save_reduce
save(state)
File "/usr/lib64/python2.7/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/usr/lib64/python2.7/pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "/usr/lib64/python2.7/pickle.py", line 663, in _batch_setitems
save(v)
File "/usr/lib64/python2.7/pickle.py", line 306, in save
rv = reduce(self.proto)
File "/usr/lib64/python2.7/copy_reg.py", line 70, in _reduce_ex
raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle file objects
除此之外,Pickle
documentation 提到它仅支持 布尔值、整数、浮点数、复数、字符串、字节对象、字节数组,和 None。因此,似乎没有希望。
编辑
如果您坚持创建进程的文件描述符,当收到来自客户端的 start
请求时,您可以使用字典将会话映射到文件描述符。
应该是这样的:
s = web.session.Session(
app, web.session.DiskStore('sessions'), initializer={"p": None})
session_map = {}
class start:
def GET(self):
session_map[s] = subprocess.Popen(['ls', '-a'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
return ""
class end:
def GET(self):
out, err = session_process[s].communicate()
session_process.pop(s, None)
s.kill
return out
我正在尝试使以下代码成为可能。但我不断收到 "TypeError: can't pickle file objects" 错误。我是 python 和 webpy 的新手。谁能告诉我如何实现此代码。
import web
import subprocess
web.config.debug = False
urls = (
"/start", "start",
"/end", "end"
)
app = web.application(urls, locals())
s = web.session.Session(app, web.session.DiskStore('sessions'), initializer={"p": None})
class start:
def GET(self):
s.p = subprocess.Popen(['ls', '-a'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return ""
class end:
def GET(self):
out, err = s.p.communicate();
return out
if __name__ == "__main__":
app.run()
我一直看到的错误是 python27/lib/python2.7/copy_reg.py”,第 70 行,_reduce_ex 引发 TypeError,"can't pickle %s objects" % base.name 类型错误:无法腌制文件对象
我自己是一个网络新手。然而,在做了一些 "research" 之后,似乎 webpy
不能 pickle
subprocess.Popen
对象 [1]。
因此,让我们尝试以下方法——即在 end
响应中创建它并打印其输出。
换句话说:
import web
import subprocess
web.config.debug = False
urls = (
"/start", "start",
"/end", "end"
)
app = web.application(urls, locals())
s = web.session.Session(
app, web.session.DiskStore('sessions'), initializer={"p": None})
class start:
def GET(self):
s.p = ['ls', '-a']
return ""
class end:
def GET(self):
out, err = subprocess.Popen(
s.p , stdout=subprocess.PIPE,
stderr=subprocess.PIPE).communicate()
s.kill() # kill the session.
return out
if __name__ == "__main__":
app.run()
[1] 如您所见:
import pickle
import subprocess
with open('bla', 'wb') as f:
pickle.dump(subprocess.Popen(['ls'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE), f)
subprocess.Popen
returns 一个文件描述符,从回溯中我推断 pickle
无法序列化文件描述符。
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "/usr/lib64/python2.7/pickle.py", line 1370, in dump
Pickler(file, protocol).dump(obj)
File "/usr/lib64/python2.7/pickle.py", line 224, in dump
self.save(obj)
File "/usr/lib64/python2.7/pickle.py", line 331, in save
self.save_reduce(obj=obj, *rv)
File "/usr/lib64/python2.7/pickle.py", line 419, in save_reduce
save(state)
File "/usr/lib64/python2.7/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/usr/lib64/python2.7/pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "/usr/lib64/python2.7/pickle.py", line 663, in _batch_setitems
save(v)
File "/usr/lib64/python2.7/pickle.py", line 306, in save
rv = reduce(self.proto)
File "/usr/lib64/python2.7/copy_reg.py", line 70, in _reduce_ex
raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle file objects
除此之外,Pickle
documentation 提到它仅支持 布尔值、整数、浮点数、复数、字符串、字节对象、字节数组,和 None。因此,似乎没有希望。
编辑
如果您坚持创建进程的文件描述符,当收到来自客户端的 start
请求时,您可以使用字典将会话映射到文件描述符。
应该是这样的:
s = web.session.Session(
app, web.session.DiskStore('sessions'), initializer={"p": None})
session_map = {}
class start:
def GET(self):
session_map[s] = subprocess.Popen(['ls', '-a'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
return ""
class end:
def GET(self):
out, err = session_process[s].communicate()
session_process.pop(s, None)
s.kill
return out