Python 在文件中的某个点追加,每次递增一个值

Python 在文件中的某个点追加,每次递增一个值,python,python-2.7,Python,Python 2.7,我对编程一无所知。这是我的第一个“适当”的项目,将被其他人使用 该程序询问各种问题,然后将新的商店条目写入文件。对于一个空文件,我可以让它大部分工作,但成品需要在现有文件中的特定点插入条目 有两个问题让我困惑不解: 如何在“Back:”之前向文件中插入新的店铺条目,以及如何在每次添加条目时将“InventoryLocation:”递增1 要附加到的文件具有以下结构: # shop 1 SuperSpaceSquids: RewardType: playercommand PriceT

我对编程一无所知。这是我的第一个“适当”的项目,将被其他人使用

该程序询问各种问题,然后将新的商店条目写入文件。对于一个空文件,我可以让它大部分工作,但成品需要在现有文件中的特定点插入条目

有两个问题让我困惑不解:

如何在“Back:”之前向文件中插入新的店铺条目,以及如何在每次添加条目时将“InventoryLocation:”递增1

要附加到的文件具有以下结构:

# shop 1
SuperSpaceSquids:
   RewardType: playercommand
   PriceType: free
   Reward:
   - ewarp Shop-SuperSpaceSquids
   MenuItem:
   - type:SKULL_ITEM
   - playerhead:MHF_Squid
   - durability:3
   - amount:1
   - name:&5SuperSpaceSquids
   - 'lore:&6&o"Squid Shop From Space!"'
   Message: ''
   InventoryLocation: 38
   ExtraPermission: ''
# shop 2
HadesKitty:
   RewardType: playercommand
   PriceType: free
   Reward:
   - ewarp Shop-HadesKitty
   MenuItem:
   - type:SKULL_ITEM
   - playerhead:Turtle_Em
   - durability:3
   - amount:1
   - name:&5HadesKitty
   - 'lore:&6&o"our prices are fair!..."'
   Message: ''
   InventoryLocation: 39 # This value needs to be incremented by 1 each time
   ExtraPermission: ''
>> insert new shops here <<
Back:
   RewardType: shop
   PriceType: free
   Reward: Shop_Menu
   MenuItem:
   - type:REDSTONE
   - amount:1
   - name:&cBack
   - lore:&8Back to Shop Menu
   InventoryLocation: 54

这是一个很好的问题。我为您编写了两个函数:

在返回之前插入(列表,列表)

insert\u before\u back
获取文件行的列表和要在
back:
之前添加的所有行的列表,然后返回一个列表,并在正确的索引中添加项目

添加库存(列表、字符串)

add_inventory
获取文件行列表和要增加其库存的店铺名称。然后,它遍历并将该数字增加1,并将列表中的值重置为新增加的值。它返回新行的列表

您可以使用这些来修改您读入的行列表,然后只需浏览列表中所有新修改的项,并将每个项以相同的名称写入文件

以下是我使用两个函数的示例:

def insert_before_back(lines, thingsToAdd):
    backIndex = lines.index('Back:\n')
    for item in reversed(thingsToAdd):
        lines.insert(backIndex, item)
    return lines

def add_inventory(lines, shopName):
    shopFound = 0
    for i in range(len(lines)):
        if shopName in lines[i]:
            shopFound = 1
        if 'InventoryLocation:' in lines[i] and shopFound:
            shopFound = 0
            lineSplit = lines[i].split(': ')
            incrementInventory = str(int(lineSplit[-1]) + 1)
            lineSplit[-1] = incrementInventory + '\n'
            lines[i] = ': '.join(lineSplit)


newLines = []
with open('input.txt', 'r') as f:
    inputLines = f.readlines()
    newLines = insert_before_back(inputLines, ['Hello\n', 'From\n', 'heinst\n'])
    add_inventory(newLines, 'HadesKitty')

with open('output.txt', 'w') as f:
    for line in newLines:
        f.write(line)

据我所知,我们无法修改文件的中间部分

您只有两个选择:

  • 将所有文件作为列表读取到内存中,然后修改列表,然后将所有列表写入文件

  • (建议)使用xml文件保存信息,但不要使用普通文件。因此,您可以使用许多工具来编写或读取它


  • 这是一个有趣的问题,海因斯特提供了一个很好的解决方案。不过,我对建筑有所保留。以下是我看到的问题,如果这是一个非常小的项目,并且预期在有限的时间内使用,则可以忽略这些问题

    并发性和并行性问题: 如果多个用户同时尝试读取和更新库存,我们需要不同的解决方案。数据库可以轻松地支持库存上的多个并发事务,而不是将文件系统作为持久存储

    可扩展性问题:
    随着事务的增加,文件大小会增加,读取整个文件并更新它将无法很好地扩展。必须使用某种方案在多个文件之间拆分事务。

    根据我的经验,“非常小”和“时间有限”的借口永远不应该使用,因为有人最终使用它的时间将超过您的计划。除了平面文件之外,我无法使用任何类型的数据库。我发布的yaml文件由minecraft插件使用,该插件不支持其他类型的存储选项。至于文件变得太大,当
    InventoryLocation
    达到52时,将创建一个新文件,因为游戏库存只能处理54个插槽。插槽53将是一个“下一页”命令,它在游戏中打开一个新的库存窗口并加载新文件。槽54返回到上一个菜单。@Ramana Kandimalla这是我的业余解决方案,用于同时编辑文件:我想指出,您的设计存在一些严重问题,这些问题太广泛,无法在本网站上回答。您应该学习数据库理论,并习惯使用两种不同的数据库(我建议以后启动SQLite和Postgres)。你自己去实现它,你会把它搞砸的。谢谢!我很难弄清楚那段代码到底是做什么的,因为有些代码我不熟悉,但我相信我最终会弄清楚的。@cyclo你到底有什么问题?别忘了接受正确的答案!:)
    def insert_before_back(lines, thingsToAdd):
        backIndex = lines.index('Back:\n')
        for item in reversed(thingsToAdd):
            lines.insert(backIndex, item)
        return lines
    
    def add_inventory(lines, shopName):
        shopFound = 0
        for i in range(len(lines)):
            if shopName in lines[i]:
                shopFound = 1
            if 'InventoryLocation:' in lines[i] and shopFound:
                shopFound = 0
                lineSplit = lines[i].split(': ')
                incrementInventory = str(int(lineSplit[-1]) + 1)
                lineSplit[-1] = incrementInventory + '\n'
                lines[i] = ': '.join(lineSplit)
    
    
    newLines = []
    with open('input.txt', 'r') as f:
        inputLines = f.readlines()
        newLines = insert_before_back(inputLines, ['Hello\n', 'From\n', 'heinst\n'])
        add_inventory(newLines, 'HadesKitty')
    
    with open('output.txt', 'w') as f:
        for line in newLines:
            f.write(line)