python - 类型错误 : can't pickle file objects webpy and subprocess

标签 python session pickle web.py

我正在尝试使以下代码成为可能。但我不断收到“TypeError:无法 pickle 文件对象”错误。我是 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,“无法 pickle %s 个对象”% base.name 类型错误:无法 pickle 文件对象

最佳答案

我自己是一个 webpy 新手。然而,在做了一些“研究”之后,似乎 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提到它 bool 值、整数、 float 、复数、字符串、字节对象、字节数组和无。因此,这似乎是无望的。

编辑

如果您坚持创建进程的文件描述符,当收到来自客户端的开始请求时,您可以使用字典将 session 映射到文件描述符。

应该是这样的:

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

关于python - 类型错误 : can't pickle file objects webpy and subprocess,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30555394/

相关文章:

session - 如何读取ServiceStack中的 session 信息

python - 为什么转储 `pickle` 比 `json` 快得多?

python - 计算 - numpy python 错误

python - 嵌套 for 循环不会给出所有输出

python - 将Column1值转换为标题,将Column2值转换为pandas中的值

node.js - Node js - 用户身份验证,在 session 中存储什么?

php - 使用 Javascript 检查 PHP session

python - 更快地计算图像 (M, N) 和模板 (3, 3) 之间的平方差之和以进行模板匹配?

python - 更新使用 cPickle 存储的字典,而不将其加载到 RAM 中

python - 用于数据库目的的最合适的 .mat 文件转换