猿问

尝试请求文件输入并将其保存在特定位置

所以我试图编写一种方法来保存用户选择的图片并将图片添加到父类“activity”中。这是我尝试过的:


    # Creating object from filedialog

    picture = filedialog.asksaveasfile(mode='r', title='Select activity picture', defaultextension=".jpg")

    

    # Check if cancelled

    if picture is None:

        return

    else:

        folder_dir = 'main/data/activity_pics'

        pic_name = 'rocket_league' #change to desc_to_img_name() later

        path = os.path.join(folder_dir, f'{pic_name}')

        

        # Making the folder if it does not exist yet

        if not os.path.exists(folder_dir):

            os.makedirs(folder_dir)

            

        # Creating a location object

        f = open(path, "a")

        

        # Writing picture on location object

        f.write(picture)

        

        # Closing

        f.close()


        # Check if successful

        if os.path.exists(path):

            print(f'File saved as {pic_name} in directory {folder_dir}')

            self.picture_path = path

后来,我使用 调用该方法rocketleague.add_picture(),其中我将 Rocketleague 定义为一个Activity类。


我尝试了在网上找到的几种不同的解决方案,但似乎都不起作用。目前,该脚本出现错误:


C:\Users\timda\PycharmProjects\group-31\venv\Scripts\python.exe C:/Users/timda/PycharmProjects/group-31/project/activities/random_activity_generator.py

Traceback (most recent call last):

  File "C:/Users/timda/PycharmProjects/group-31/project/activities/random_activity_generator.py", line 160, in <module>

    rocketleague.add_picture()

  File "C:/Users/timda/PycharmProjects/group-31/project/activities/random_activity_generator.py", line 46, in add_picture

    f.write(picture)

TypeError: write() argument must be str, not _io.TextIOWrapper

所以我猜我的 open.write() 除了字符串之外不适合任何东西。我不确定我当前的方法是否有效。


执行此操作最方便的方法是什么?


MMTTMM
浏览 109回答 1
1回答

呼啦一阵风

根据您的描述,您正在使用完全不同的方法来完成任务。我将首先解释您想要做什么以及为什么它不起作用。-> 因此,在您要求用户选择一个文件并创建folder_dir和path后,您希望将所选图片移动/复制到变量 描述的位置path。问题,根据您的需要,您可能就在这里,但我觉得您应该使用filedialog.askopenfile()而不是filedialog.asksaveasfile(),因为您可能希望他们选择一个文件,而不是选择一个文件夹来将文件移动到 - 您似乎已经有了目的地folder_dir。但这又取决于您的需求。重要的一个。在您的代码中,其中一条注释显示:“”“创建位置对象”“”您使用的f = open(path, "a"),您没有在那里创建位置对象。f只是一个file以文本追加模式打开的对象 - 如函数调用"a"中的第二个参数所示open()。您无法将二进制图像文件写入文本文件。这就是为什么错误消息说它期望将字符串写入文本文件,而不是二进制 I/O 包装器。解决方案很简单,使用实际方法移动文件来执行任务。因此,一旦您有了图像文件的地址(由用户在filedialog上面解释的中选择),请注意,正如@Bryan 指出的那样,picture变量将始终file handler是用户选择的文件的地址。.name我们可以使用.txt文件的属性来获取所选文件的绝对地址file handler。>>> import tkinter.filedialog as fd>>> a = fd.askopenfile()# I selected a test.txt file>>> a<_io.TextIOWrapper name='C:/BeingProfessional/projects/Py/test.txt' mode='r' encoding='cp1252'># the type is neither a file, not an address.>>> type(a)<class '_io.TextIOWrapper'>>>> import os# getting the absolute address with name attribute>>> print(a.name)C:/BeingProfessional/projects/Py/test.txt# check aith os.path>>> os.path.exists(a.name)True注意:我们还可以使用filedialog.askopenfilename()它仅返回所选文件的地址,这样您就不必担心文件处理程序及其属性。我们已经有了目的地folder_dir和要给出的新文件名。这就是我们所需要的,源和目的地。这是复制文件的操作这三种方法完成相同的工作。根据需要使用其中任何一个。import osimport shutilos.rename("path/to/current/file.foo", "path/to/new/destination/for/file.foo")shutil.move("path/to/current/file.foo", "path/to/new/destination/for/file.foo")os.replace("path/to/current/file.foo", "path/to/new/destination/for/file.foo")请注意,您必须在源参数和目标参数中包含文件名 (file.foo)。如果更改,文件将被重命名并移动。另请注意,在前两种情况下,创建新文件的目录必须已经存在。在 Windows 计算机上,具有该名称的文件一定不存在,否则exception将会引发错误,但os.replace()即使在这种情况下,也会默默地替换文件。您的代码已修改# Creating object from filedialogpicture = filedialog.askopenfile(mode='r', title='Select activity picture', defaultextension=".jpg")# Check if cancelledif picture is None:&nbsp; &nbsp; returnelse:&nbsp; &nbsp; folder_dir = 'main/data/activity_pics'&nbsp; &nbsp; pic_name = 'rocket_league' #change to desc_to_img_name() later&nbsp; &nbsp; path = os.path.join(folder_dir, f'{pic_name}')&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; # Making the folder if it does not exist yet&nbsp; &nbsp; if not os.path.exists(folder_dir):&nbsp; &nbsp; &nbsp; &nbsp; os.makedirs(folder_dir)&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp;# the change here&nbsp; &nbsp;shutil.move(picture.name, path)&nbsp; # using attribute to get abs address&nbsp; &nbsp; # Check if successful&nbsp; &nbsp; if os.path.exists(path):&nbsp; &nbsp; &nbsp; &nbsp; print(f'File saved as {pic_name} in directory {folder_dir}')&nbsp; &nbsp; &nbsp; &nbsp; self.picture_path = path该代码块的缩进不是很好,因为原始问题格式的缩进没有那么好。
随时随地看视频慕课网APP

相关分类

Python
我要回答