在Python中写入文件,但只替换d的某个实例

2024-04-23 15:38:28 发布

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

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

代码基本上贯穿每一行。如果不是我想编辑的那一行,我就按原样重写这一行。但是如果这是我要编辑的行,我就使用REPLACE函数来更改字段,在本例中是username(它被变量“diff\u 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)

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

当然,问题是replace函数将替换该行中与line.strip().split(", ")[0]中的文本匹配的所有文本实例。你知道吗

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

我不想重写太多。有没有什么方法可以修改当前的代码来限制writelines或者替换函数来查看行中的特定字段而不是每个实例?我知道用replace我只能说第n个实例应该被替换,但问题是我不知道要替换的有效项是第1个、第2个还是第11个。。。(作为第一个字段的username字段只是一个示例,但是还可以替换文件中的后面的字段)。你知道吗

如果没有捷径,我该如何重写逻辑来处理这个问题?你知道吗

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

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]任务.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

2]用户.txt

admin, adm1n
test, t3st
blah, kkijh
gerhard, test123#
gerhardl, 555%%%
diana, test123
maya, 12test
jannie, password!
sannie, password123
zuma, ???
harley, test11

Tags: andthetotaskdataifwithline
2条回答

可以在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.

我知道你说过你不想改变密码。不过,我能想到的解决办法是使用熊猫。你知道吗

您可以读取csv文件并将其存储到数据帧中,然后可以访问username列并仅替换其值。应该是这样的。你知道吗

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')

相关问题 更多 >