Python 2.6.4元帅。装载不接受用子流程.Popen

2024-09-27 22:21:25 发布

您现在位置:Python中文网/ 问答频道 /正文

这真是个不幸的情况。Maya 2011附带2.6.4,但此代码在其中不起作用:

pipe = subprocess.Popen( 'p4 -G edit C:/somefile.txt', stdout=subprocess.PIPE).stdout

try:
    while 1:
        record = marshal.load( pipe )
        list.append( record )
except EOFError:
    pass

各种2.5版本都可以工作,最新的2.6.5也可以工作,只是不是Maya附带的版本,当然!它抛出以下错误:

^{pr2}$

最好的行动方案是什么?在

为了继续生活,代码被改为只转储一个文件,所以元帅。装载然后加载一个实际的文件。虽然这是可行的,但它是跛脚的。在

maya2011通过zip访问python所以作为一个小测试,我压缩了2.6.5的Python26/Lib并交换了系统路径指向2.6.4压缩包到2.6.5压缩包的条目。虽然我还没有对此进行过广泛的测试,但这似乎有效。我不知道这个主意比上面的好还是坏。在

理想的情况下(我认为)在2.6.4中我可以做一些事情来实现这一点,而不需要混合python版本或将temp文件一直写到磁盘上。有什么想法吗?在

更新关于元帅。载荷()

尝试元帅。载荷(),因为它不会出错,但仍然不能一直工作。我肯定是在黑暗中摸索这些东西。如果文件操作是单独进行的,那么perforce的速度慢得令人无法忍受,因此必须在一个查询中执行这些操作。原始代码是这样做的:

files = [a,b,c...n] # Huge list of files
p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
(fi, pipe) = (p.stdin, p.stdout)

# Fill the command up with all the files
for file in files:
    fi.write(file + '\n')
fi.close()

# Get all the results
try:
    while 1:
        record = marshal.load( pipe )
        listData.append( record )
except EOFError:
    pass

我不知道为什么这会起作用(在2.5.x/2.6.5中),但它确实起作用;listData最终以所有文件结果的列表形式结束。我不知道该怎么做元帅。载荷(),我只得到第一个结果。这个方法几乎是一字不差地从perforce中提取的,所以我知道这是应该这样做的。很容易想象,我只是不知道如何正确地使用子进程和封送。在

更新2元帅。载荷()完全管用!

经过更多的测试,管道。读取()提供了所有数据,但它包含一些空字符或其他我无法完全理解的内容元帅。载荷()只读取第一个条目。在这种特殊情况下,我可以分割“{”上的数据并收集数据。在

listData = []
results = pipe.read().split("{")
# Skip the first entry since it's empty
for result in results[1:]:
    listData.append( marshal.loads( "{" + result) )

感谢克里斯蒂安为我指出了正确的方向,希望任何使用perforce升级到maya2011的人都能让事情变得更顺利。在


Tags: 文件the代码版本stdout情况filesrecord
3条回答

在使用-G选项解组p4的输出时遇到了相同的问题。marshal.loads(str)只读取第一条记录,marshal.load(StringIO(str))失败,返回'元帅。装载()参数必须是file'。 建议我使用临时文件解决方法,而不是拆分:

import subprocess, marshal, tempfile

tempf = tempfile.TemporaryFile()
subprocess.Popen(cmd, stdout=tempf).communicate()
tempf.seek(0)
try:
    while 1:
        record = marshal.load(tempf)
        listData.append( record )
except EOFError:
    pass
tempf.close()

请注意,一旦关闭临时文件,python就会为您删除它。在

最后我还是选择了这个。在

import shutil
import os
import tempfile

def decode_list(outputstr):
  tmpfolder = tempfile.mkdtemp()
  try:
      binname = os.path.join(tmpfolder, "p4_decode.bin")
      with open(binname, "wb") as binfile:
          binfile.write(outputstr)

      with open(binname, "rb") as binfile:
          ret = []
          while True:
              try:
                  item = marshal.load(binfile)
                  ret.append(item)
              except EOFError:
                  return ret
  finally:
      if tmpfolder and os.path.isdir(tmpfolder):
          shutil.rmtree(tmpfolder)

这是一个老问题,但我想我应该补充一下我在其他遇到这个问题的人身上的发现。在

不幸的是,senyacap的答案在Windows上似乎不起作用,marshal.load(tempf)无法说明临时文件不是文件对象。传入tempf.file也不起作用。在

因此,另一个(可怕的)解决方法(这是专门针对Perforce的,因为没有其他选项可以使用marshal模块),是:

p = subprocess.Popen ( cmd, stdout = subprocess.PIPE ) 
( stdoutdata, stderrdata ) = p.communicate ( )

unmarshalled = []
while stdoutdata:
    record = marshal.loads ( stdoutdata )
    unmarshalled.append ( record )
    remarshalled = marshal.dumps ( record )
    stdoutdata = stdoutdata [ len ( remarshalled ) : ]

相关问题 更多 >

    热门问题