2016-11-11 86 views
2

我还在用python复制并替换行,问题Here。基本上,我想统计某个部分中某个模式的数量,然后在行中进行更新。我想我已经在我的问题中发现了这个问题:我调用一个子函数来在主函数中使用同一个文件,并且这个函数在时间上变得混乱起来。我对编程非常陌生,我不知道如何以另一种方式做这个copy-statistics-replace-copy事情。任何建议或提示是值得欢迎的。调用函数中的子函数来处理Python中的同一个文件?

下面是部分代码是我现在得到:

# sum number of keyframes 
def sumKeys (sceneObj, objName): 
    sceneObj.seek(0) 
    block = [] 
    Keys = "" 
    for line in sceneObj: 
     if line.find("ObjectAlias " + objName + "\n") != -1: 
      for line in sceneObj: 
       if line.find("BeginKeyframe") != -1: 
        for line in sceneObj: 
         if line.find("default") != -1: 
          block.append(line.rstrip()) 
          Keys = len(block) 
         elif line.find("EndKeyframe") != -1: 
          break 
        break 
      break 
    return (Keys) 

# renew number of keyframes 
def renewKeys (sceneObj, objName): 
    sceneObj.seek(0) 
    newscene = "" 
    item = [] 
    for line in sceneObj: 
     newscene += line 
     for obj in objName: 
      if line.find("ObjectAlias " + obj + "\n") != -1: 
       for line in sceneObj: 
        if line.find("EndKeyframe") != -1: 
         newscene += line 
         break 
        if line.find("BeginKeyframe") != -1: 
         item = line.split() 
         newscene += item[0] + " " + str(sumKey(sceneObj, obj)) + " " + item[-1] + "\n" 
         continue 
        else: 
         newscene += line 
    return (newscene) 

原文:

lines 
BeginObjects 
lines 
ObjectAlias xxx 
lines 
BeginKeyframe 34 12 ----> 34 is what I want to replace 
lines 
EndObject 
BeginAnotherObjects 
... 

目标:

lines 
BeginObjects 
lines 
ObjectAlias xxx 
lines 
BeginKeyframe INT 12 ---->INT comes from sumKeys function 
lines 
EndObject 
BeginAnotherObjects 
... 
+0

所以,你要找到'BeginKeyframe'部分在文件中,统计包含'default'的'BeginKeyframe'和'EndKeyframe'之间的所有行,并更新'BeginKeyframe'行以包含该数字?那是对的吗?有点难以确定你想要做什么。也许你可以澄清。 – sloth

+0

@sloth是的,你是对的。 ** BeginKeyframe **和** EndKeyframe **之间有许多行,我需要计算**默认**模式并将其放入** BeginKeyframe **行以替换原始INT。我还需要一个函数来处理其他一些**对象**(如ObjectAlias xxx)。我不是英国人,我很难说出我的意思。 – Tian

回答

1

您可以使用tellseek到一个文件中移动,所以要做你想做的事情,你可以使用这样的东西,我砍了醚:

import re 

# so, we're looking for the object 'HeyThere' 
objectname = 'HeyThere' 

with open('input.txt', 'r+') as f: 
    line = f.readline() 
    pos = f.tell() 
    found = False 
    while line: 

     # we only want to alter the part with the 
     # right ObjectAlias, so we use the 'found' flag 
     if 'ObjectAlias ' + objectname in line: 
      found = True 
     if 'EndObject' in line: 
      found = False 

     if found and 'BeginKeyframe' in line: 

      # we found the Keyframe part, so we read all lines 
      # until EndKeyframe and count each line with 'default' 
      sub_line = f.readline() 
      frames = 0 
      while not 'EndKeyframe' in sub_line: 
       if 'default' in sub_line: 
        frames += 1 
       sub_line = f.readline() 

      # since we want to override the 'BeginKeyframe', we 
      # have to move back in the file to before this line 
      f.seek(pos) 

      # now we read the rest of the file, but we skip the 
      # old 'BeginKeyframe' line we want to replace 
      f.readline() 
      rest = f.read() 

      # we jump back to the right position again 
      f.seek(pos) 

      # and we write our new 'BeginKeyframe' line 
      f.write(re.sub('\d+', str(frames), line, count=1)) 

      # and write the rest of the file 
      f.write(rest) 
      f.truncate() 
      # nothing to do here anymore, just quit the loop 
      break 

     # before reading a new line, we keep track 
     # of our current position in the file 
     pos = f.tell() 
     line = f.readline() 

这些评论几乎可以解释发生了什么。

鉴于像

foo 
bar 
BeginObject 
something 
something 
ObjectAlias NotMe 
lines 
more lines 
BeginKeyframe 22 12 
foo 
bar default 
foo default 
bar default 
EndKeyframe 
EndObject 
foo 
bar 
BeginObject 
something 
something 
ObjectAlias HeyThere 
lines 
more lines 
BeginKeyframe 43243 12 
foo 
bar default 
foo default 
bar default 
foo default 
bar default 
foo default 
bar 
EndKeyframe 
EndObject 

输入文件将取代线

BeginKeyframe 43243 12 

BeginKeyframe 6 12 
+0

抱歉,延迟。感谢代码示例,特别是评论。我花了整整一晚的时间去了解它,这有点不在我的范围之内。所以关键是逐行跟踪,对吗?但为什么我需要readline?似乎for循环interate不需要。另外,我在哪里添加对象interate来处理多个对象替换?换句话说,我怎么能替代其他对象,如HeyYou,LookHere ... – Tian

+0

尝试使用'打开'像打开文件在图形texteditor;鼠标光标位于文本的开头。当您使用readline时,光标跳转到当前行的末尾。现在,因为我们要在BeginImageframe行下面计算一些行,所以我们必须继续读取行,但是我们想要在读取该块的所有行之后跳回到BeginKeyframe行(因此我们使用seek) 。这对于for循环来说是不可能的,因为它“只向前移动”。要实际处理多个对象,再次使用'seek'跳回到文件中而不是使用'break' .... – sloth

+0

...并更改'if'ObjectAlias'+ objectname in line:'like something' ('HeyYou','LookHere','WhatEver']中的''ObjectAlias'+ n'):' – sloth

相关问题