我正在努力使以下代码成为可能。但我一直得到" TypeError:不能腌制文件对象"错误。我是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()
我一直看到的错误是 _reduce_ex中的python27 / lib / python2.7 / copy_reg.py",第70行 引发TypeError,"不能腌制%s对象" %base。名称 TypeError:不能腌制文件对象
答案 0 :(得分:1)
我,我自己,一个网络新手。然而,在做了一些“研究”之后,似乎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
返回一个文件描述符,并从追溯中推断出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还提到它支持仅布尔值,整数,浮点数,复数,字符串,字节对象,字节数组和无。因此,它似乎毫无希望。
如果您坚持创建进程'文件描述符,则在从客户端收到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