Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中写入文件,但仅替换某些数据实例_Python_File_Replace - Fatal编程技术网

在Python中写入文件,但仅替换某些数据实例

在Python中写入文件,但仅替换某些数据实例,python,file,replace,Python,File,Replace,我有一段代码,它应该替换逗号分隔文件中的特定字段。在下面的示例中,它将替换任务分配给的用户。当前用户是文件中的第一个字段。在代码的前一部分中,我确定了要编辑的文件的相关行(存储为“edit_line”变量) 代码基本上贯穿每一行。如果它不是我想要编辑的那一行,我就按原样重写这一行。但是如果它是我想要编辑的行,我使用REPLACE函数来更改字段,在本例中是username(它被变量“diff_user”的值替换) 除了一个逻辑错误外,这个方法非常有效,但我是一个新手,直到它意外发生才想到它 当然,

我有一段代码,它应该替换逗号分隔文件中的特定字段。在下面的示例中,它将替换任务分配给的用户。当前用户是文件中的第一个字段。在代码的前一部分中,我确定了要编辑的文件的相关行(存储为“edit_line”变量)

代码基本上贯穿每一行。如果它不是我想要编辑的那一行,我就按原样重写这一行。但是如果它是我想要编辑的行,我使用REPLACE函数来更改字段,在本例中是username(它被变量“diff_user”的值替换)

除了一个逻辑错误外,这个方法非常有效,但我是一个新手,直到它意外发生才想到它

当然,问题是replace函数将替换该行中与
line.strip().split(“,”[0]
中的文本匹配的文本的每个实例

因此,如果我有一个名为“ADMIN”的当前用户,并且在同一行中我稍后有文本“ADMIN”(例如,在任务描述中),那么这两个文本都将被新用户名替换,而不仅仅是行的第一个字段中存在的当前用户名

我宁愿不做大的重写。是否有任何方法可以修改当前代码,将writeline或replace函数限制为查看行中的特定字段,而不是每个实例?我知道用replace我可以说只有第n个实例应该被替换,但问题是我不知道要替换的有效项是第1个、第2个还是第11个。。。(用户名字段(第一个字段)只是一个示例,但也可以替换文件中的后续字段)

如果没有捷径,我如何重写逻辑来处理这个问题

更新:这是整个函数,因此有人可以执行它。此代码实际上是课程的一部分:

def edit_task(task_number):
    class ExistException(Exception):  # Custom exception used later
        pass
    choice = ""  # used later
    edit_line = int(task_number) - 1  # Line of file to be edited (starts at 0, hence the minus 1)
    tf = open("tasks.txt","r")  # Open task file for reading first
    data = tf.readlines()
    print(f"EDIT TASK {task_number}:\n")

    # Split the selected task (edit_line) into separate fields:
    task_un = data[edit_line].strip().split(", ")[0]  # Stores username
    task_title = data[edit_line].strip().split(", ")[1]  # Stores title
    task_desc = data[edit_line].strip().split(", ")[2]  # Stores description
    task_cd = data[edit_line].strip().split(", ")[3]  # Stores create date
    task_dd = data[edit_line].strip().split(", ")[4]  # Stores due date
    task_ci = data[edit_line].strip().split(", ")[5]  # Stores completion indicator

    # Print out task detail:
    print(f"Task {task_number}: {task_title}")
    print(f"Description:    {task_desc}")
    print(f"Assigned to:    {task_un}")
    print(f"Created on:     {task_cd}")
    print(f"Due Date:       {task_dd}")
    print(f"Completed?:     {task_ci}")
    print("")


    # Check if already done, print accordingly and return to previous menu:
    if task_ci == 'Yes':
        print("\nThis task is already completed, and cannot be edited.\n")
        view_mine()

    # Give user different options to edit task:
    edit_option = input(f"Type 'DONE' to mark task {task_number} as completed.\n"
    "Type 'USER' to assign the task to someone else.\n"
    "Type 'DATE' to change the due date.\n"
    "Type any other key to go back to the main menu:\n-->").lower()

    # User selected to mark as completed:
    if edit_option == 'done':
        task_ci = 'Yes'  # change variable
        with open("tasks.txt",'w') as f:
            # Go through file line by line and rewrite the data:
            for i, line in enumerate(data):
                # If relevant line (selected task) replace necessary field:
                if i == edit_line:
                    f.writelines(line.replace(line.strip().split(", ")[5], "Yes"))
                # For other lines, just replace with same data again
                else:
                    f.writelines(line)
            tf.close()
            # Print updated task:
            print(f"Task {task_number} marked as completed:\n")
            print(f"Task {task_number}: {task_title}")
            print(f"Description:    {task_desc}")
            print(f"Assigned to:    {task_un}")
            print(f"Created on:     {task_cd}")
            print(f"Due Date:       {task_dd}")
            print(f"Completed?:     {task_ci}")   
            print("")

            option = input("Type '-1' to go back to the Main Menu, "
            "or any other key to exit.\n--> ").lower()
            if option == '-1':
                mainMenu()
            else:
                print("Goodbye")
                exit()

    # User selected to assign to someone else:
    elif edit_option == 'user':
        while True:
            try:
                # Refer to ELSE portion below. if username does NOT exist, user can try again 
                #(stored as choice, and this becomes input)
                if choice != "":  
                    diff_user = choice
                else: # if choice is still null, then this is first time entry attempt:
                    print("Enter the username of the person the "
                    "task should be assigned to:")
                    print (f"Available users: {users}")
                    diff_user = input("\n-->").lower()
                # Loop through file to check if user exists. Must count it at least once:
                if diff_user in users:
                    task_un = diff_user
                    with open("tasks.txt",'w') as f:
                        # Go through file line by line and rewrite the data:
                        for i, line in enumerate(data):
                            # If relevant line (selected task) replace necessary field:
                            if i == edit_line:
                                f.writelines(line.replace(line.strip().split(", ")[0], diff_user))
                            # For other lines, just replace with same data again
                            else:
                                f.writelines(line)
                    tf.close()
                    # Print updated task:
                    print(f"Task {task_number} assigned to '{diff_user}'\n")
                    print(f"Task {task_number}: {task_title}")
                    print(f"Description:    {task_desc}")
                    print(f"Assigned to:    {task_un}")
                    print(f"Created on:     {task_cd}")
                    print(f"Due Date:       {task_dd}")
                    print(f"Completed?:     {task_ci}")   
                    print("")

                    option = input("Type '-1' to go back to the Main Menu, "
                    "or any other key to exit.\n--> ").lower()
                    if option == '-1':
                        mainMenu()
                    else:
                        print("Goodbye")
                        exit()
                # If username does NOT exist, throw error and ask user to go to registration, OR
                # try enter username again:
                else:  
                    print("This user does not exist. Press 'R' to register them, or enter a"
                    " different username:")
                    print (f"Available users: {users}")
                    choice = input("\n-->").lower()  # store username and go back to start if loop
                    if choice == 'r':            #... unless they chose, "R" the go to Registration
                        reg_user()
                    else:
                        raise ExistException
            except ExistException:
                pass

    # User selected to change due date:
    elif edit_option == 'date':
        new_due_date = date_val()  # Calls function to enter & validate date, & returns variable
        with open("tasks.txt",'w') as f:
            # Go through file line by line and rewrite the data:
            for i, line in enumerate(data):
                # If relevant line (selected task) replace necessary field:
                if i == edit_line:
                    f.writelines(line.replace(line.strip().split(", ")[4], new_due_date))
                # For other lines, just replace with same data again
                else:
                    f.writelines(line)
        tf.close()
        print(f"Due Date \'{task_dd}\' changed to '{new_due_date}'.")
        option = input("Type '-1' to go back to the Main Menu, "
        "or any other key to exit.\n--> ").lower()
        if option == '-1':
            mainMenu()
        else:
            print("Goodbye")
            exit()
    else:
        print("Returning to Main Menu\n")
        mainMenu()
您需要参考我在此处命名的文件,并提供以下几行:

1]tasks.txt

admin, Register Users with taskManager.py, Use taskManager.py to add the usernames and passwords for all users that will be using this program., 10 Oct 2019, 20 Dec 2019, Yes
admin, Assign initial tasks, Use taskManager.py to assign each non-admin team member with appropriate tasks, 10 Oct 2019, 25 Dec 2019, Yes
gerhard, Test program, run through all program functions to test it, 11 Dec 2019, 27 Dec 2019, Yes
admin, Add comments to program, make sure entire .py file has comments for easy reading, 11 Dec 2019, 12 Jan 2020, No
diana, UAT, do user acceptance testing on the program, 11 Dec 2019, 15 Mar 2020, No
test, Program Sign-off, Department Manager to sign off on UAT so program can be implemented, 12 Dec 2019, 31 Mar 2020, No
gerhard, Example task, This is just an example of what a task description might look like with a duplicate gerhard, 12 Dec 2019, 14 Jun 2021, No
diana, water the plants, every week all the plants must be watered, 12 Dec 2019, 12 Jan 2019, No
admin, Test blah , blah blah blah, 24 Dec 2019, 12 Feb 2020, No
gerhard, print all, All tasks to be printed and filed, 26 Dec 2019, 13 Feb 2021, No
admin, adm1n
test, t3st
blah, kkijh
gerhard, test123#
gerhardl, 555%%%
diana, test123
maya, 12test
jannie, password!
sannie, password123
zuma, ???
harley, test11
2]users.txt

admin, Register Users with taskManager.py, Use taskManager.py to add the usernames and passwords for all users that will be using this program., 10 Oct 2019, 20 Dec 2019, Yes
admin, Assign initial tasks, Use taskManager.py to assign each non-admin team member with appropriate tasks, 10 Oct 2019, 25 Dec 2019, Yes
gerhard, Test program, run through all program functions to test it, 11 Dec 2019, 27 Dec 2019, Yes
admin, Add comments to program, make sure entire .py file has comments for easy reading, 11 Dec 2019, 12 Jan 2020, No
diana, UAT, do user acceptance testing on the program, 11 Dec 2019, 15 Mar 2020, No
test, Program Sign-off, Department Manager to sign off on UAT so program can be implemented, 12 Dec 2019, 31 Mar 2020, No
gerhard, Example task, This is just an example of what a task description might look like with a duplicate gerhard, 12 Dec 2019, 14 Jun 2021, No
diana, water the plants, every week all the plants must be watered, 12 Dec 2019, 12 Jan 2019, No
admin, Test blah , blah blah blah, 24 Dec 2019, 12 Feb 2020, No
gerhard, print all, All tasks to be printed and filed, 26 Dec 2019, 13 Feb 2021, No
admin, adm1n
test, t3st
blah, kkijh
gerhard, test123#
gerhardl, 555%%%
diana, test123
maya, 12test
jannie, password!
sannie, password123
zuma, ???
harley, test11

我知道您说过不想更改代码。然而,我能想到的解决办法是使用熊猫

您可以读取将其存储到数据框中的csv文件,然后可以访问用户名列并仅替换其值。应该是这样的

import pandas as pd

# Read the csv
df = pd.read_csv('my_old_file.csv')

# Update the desired row
df.loc[edit_line,'username'] = diff_user

# Save the new dataframe
df.to_csv('replaced_value.csv')

您可以在
replace
函数中使用可选的
count
参数:

str.replace(old, new[, count])
Return a copy of the string with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced.

对字段本身的内容调用
replace()
,而不是调用
line.replace()
。然后用
,“
将所有字段再次连接在一起,以获得新行。如果你提供了一个最小的、可验证的例子,我会用一个例子给你一个答案?这里有一个:“管理员,分配初始任务,使用taskManager.py为每个非管理员团队成员分配适当的任务,2019年10月10日,2019年12月25日,是的”我可以在我的原始问题中添加更多内容,只是想确保我理解您想要的内容。
f.writelines
通常用于编写行列表。否则它只是
f.write
(加上linefeed)我的意思是我实际上可以自己执行的代码。否则,在回答您的问题之前,我必须自己重新创建您的运行时场景。有时候我有时间,但今天不行。@DanielFarrell你的回答引导我弄明白了,谢谢。如果使用replace,只需使用超级手动,从头开始重新构建整行。如前所述,我不知道我要替换的计数器值是多少。如前所述,我不知道我要替换的计数器值是多少。