首页 > 编程问答 >Python 将脚本转换为 exe 并给出 PermissionError

Python 将脚本转换为 exe 并给出 PermissionError

时间:2024-08-01 04:49:24浏览次数:14  
标签:python runtime-error permission-denied

我有一个 Python (Windows 10) 脚本,其功能之一是创建备份。这是函数:

def create_backups(self, file: str, counter: int = None) -> None:
    counter = counter or 1
    res = self.re_obj.match(file)
    if res is None or len(res.groups()) == 0:
        back_file = f"{file} ({counter}).{self.ext}"
    else:
        l_res = re.search("\\w[\\w\\s]+?\\.[a-zA-Z_]\\w{2}", file)
        file_name, file_ext = splitext(l_res.group())
        back_file = f"{file_name}{file_ext} ({counter}).{self.ext}"
    if exists(back_file) and counter < self.n_copies:
        counter += 1
        self.create_backups(back_file, counter)
    with open(file, "rb") as f_src, open(back_file, "wb") as f_dst:
        shutil.copy2(f_src, f_dst)
    if self.verbose:
        print(f"Copied {file} to '{back_file}'")

它应该制作多个副本(参数化)。如您所见,如果 back_file 已经存在,它会调用自身。模式如下:

test.txt
test.txt (1).sav
test.txt (2).sav
...
test.txt (n).sav

n 取决于参数 n_copies

如果我将其转换为 exe 文件,它仍然可以在 PowerShell 中工作。但是,如果我尝试从另一个程序运行它,它会在第二个副本上引发 PermissionError 异常 test.txt (1).sav 例如,我使用 FreeCommander XE 并且我尝试按如下方式运行脚本:

backup.exe run in FreeCommander XE

参数如下:

  • -f 文件名和 FreeCommander 替换 %ActivSel% 与选择
  • -n 否。副本
  • -e 扩展名,例如 sav
  • -b 备份方法

如果我从 PowerShell 运行等效的参数化脚本:

backup.exe -f "test.txt" -n 14 -e "sav"

一切正常。它位于 FreeCommander 我所在的位置 PermissionError 恰好在

shutil.copy2(f_src, f_dst)

我也尝试以管理员身份运行 FreeCommander 没有区别。

我是不知道如何解决这个问题。有什么想法吗?

编辑:调试详细信息:

Traceback (most recent call last):
  File "backup.py", line 244, in <module>
  File "backup.py", line 78, in create_backups
  File "backup.py", line 79, in create_backups
PermissionError: [Errno 13] Permission denied: 'test.txt (2).sav'
[21056] Failed to execute script 'backup' due to unhandled exception!

这个问题很可能是由于文件锁定引起的。当你在 FreeCommander 中选择一个文件时,该文件可能还在被 FreeCommander 自身或其他程序占用,导致 Python 脚本无法写入该文件。

以下是一些可能的解决方案:

1. 关闭可能占用文件的程序:

在运行脚本之前,确保没有其他程序正在使用你要备份的文件。这包括 FreeCommander 自身。尝试先关闭 FreeCommander ,然后从命令行运行脚本,看看问题是否解决。

2. 使用文件复制库:

标准库中的 shutil.copy2() 函数可能会受到文件锁定的影响。你可以尝试使用更强大的文件复制库,例如 pywin32 ,它可以更好地处理文件锁定情况。

以下是使用 pywin32 库复制文件的示例代码:

import win32file
import win32con

def create_backups(self, file: str, counter: int = None) -> None:
    # ... (其他代码) ...

    with open(file, "rb") as f_src:
        with open(back_file, "wb") as f_dst:
            # 使用 pywin32 复制文件
            size = win32file.GetFileSize(f_src.fileno())
            data = win32file.ReadFile(f_src.fileno(), size)[1]
            win32file.WriteFile(f_dst.fileno(), data)
            # 设置文件属性
            win32file.SetFileAttributes(
                back_file,
                win32file.GetFileAttributes(file) & ~win32con.FILE_ATTRIBUTE_READONLY
            )

    # ... (其他代码) ...

3. 使用 try-except 块处理异常:

你可以使用 try-except 块来捕获 PermissionError 异常,并在遇到异常时尝试其他操作,例如:

  • 等待一段时间后重试
  • 提示用户关闭占用文件的程序
  • 将文件复制到临时位置,然后再移动到目标位置

以下是一个使用 try-except 块处理异常的示例代码:

def create_backups(self, file: str, counter: int = None) -> None:
    # ... (其他代码) ...

    try:
        with open(file, "rb") as f_src, open(back_file, "wb") as f_dst:
            shutil.copy2(f_src, f_dst)
    except PermissionError:
        # 处理异常,例如:
        # print(f"无法复制文件 '{file}',文件可能正在使用中。")
        # time.sleep(5)  # 等待 5 秒后重试
        # raise  # 重新抛出异常,让程序崩溃

    # ... (其他代码) ...

4. 检查文件权限:

确保你的 Python 脚本有足够的权限写入目标文件夹。你可以尝试右键单击目标文件夹,选择“属性”,然后在“安全”选项卡中检查你的用户帐户是否具有“写入”权限。

其他建议:

  • 使用调试器逐步执行代码,查看程序在哪个步骤出现问题。
  • 在代码中添加日志记录,以便更好地了解程序的执行过程。

希望以上解决方案能够帮助你解决问题。如果问题仍然存在,请提供更多详细信息,例如:

  • 你的 Python 版本
  • 你使用的 pyinstaller 版本
  • 完整的错误消息和堆栈跟踪信息

标签:python,runtime-error,permission-denied
From: 78816931

相关文章

  • conda update python 不会更新,但 conda update --all 会更新
    我正在尝试更新我的venv。这就是我看到的(base_test)>condaupdatepythonCollectingpackagemetadata(current_repodata.json):doneSolvingenvironment:done==>WARNING:Anewerversionofcondaexists.<==currentversion:4.10.3latestversion:24......
  • 如何使用 Selenium (python) 访问另一个影子根中影子根中的元素?
    我有以下代码和HTML结构(我不是这方面的专家)。我正在尝试抓取HTML代码末尾的96.00C元素,其路径是:Xpath://*[@id="_grid"]/set-class2/div2/text-binding//text()完整Xpath:/html/body/main/div/div3/div3/......
  • 在Python中,如何在一段时间内接受输入
    我正在尝试用Python制作一个蛇游戏,但不知道如何制作它,以便蛇在没有玩家输入的情况下继续移动,所以如果有人知道一个简单的方法来做到这一点,我需要在2秒后取消输入将不胜感激代码如下:importrandomimportsysplayerY=(1)playerX=(0)appleY=random.randint(1,10)appl......
  • 在Python中单步执行代码时是否可以引发异常
    当我在IDE(例如PyCharm)中单步执行代码时,我想转储函数的参数(以供以后使用,例如复制它)。计划的场景是在某处设置断点,然后引发异常(这不在我运行的代码中,这就是重点),并捕获它。代码应该如下所示:defexception_cathcher_decorator(func):try:returnfunc(*f_args,**f_k......
  • 解决python自动化操作异常处理的问题
    在python自动化领域,往往要用到pyautogui,pywin32等模块实现自动化操作。然而,这种自动化操作,本身具有一定的局限性,其中最主要的一个问题就是,一旦执行结果不按照脚本预设的来执行,往往会抛出异常,导致程序中断。解决这个问题,主要有这么几种思路:第一,每一次操作后分情况讨论。这种方......
  • Python爬虫入门03:用Urllib假装我们是浏览器
    文章目录引言Urllib库简介Request模块详解Error模块与异常处理Parse模块与URL解析Robotparser模块模拟浏览器请求使用Request方法添加请求头信息代码示例1.设置请求URL和请求头2.定义请求参数并转换为适当的格式3.使用Request方法封装请求4.发送请求并获取响应常用......
  • 请以零基础学Python 之 第二十讲 分组和贪婪匹配
    当我们处理字符串时,有时候需要根据特定的模式来分割或者提取信息。Python提供了强大的正则表达式库re,可以帮助我们实现这些复杂的字符串操作。本篇博客将介绍两个常用的正则表达式技巧:分组和贪婪匹配。分组(Grouping)在正则表达式中,分组是将多个模式单元组合为一个单元,以便......
  • 零基础学python 之 第十九讲 正则表达式
    当你开始学习Python编程时,正则表达式是一项非常强大的工具,用于处理文本数据中的模式匹配和搜索。本篇博客将带你从零开始学习如何在Python中使用正则表达式。1.什么是正则表达式?正则表达式(RegularExpression)是用于描述字符串模式的一种工具,可以用来匹配、查找、替换符合特......
  • python之贪吃蛇
    废话不多说,直接上代码(确保已经安装pygame)importpygameimportrandom#基础设置#屏幕高度SCREEN_HEIGHT=480#屏幕宽度SCREEN_WIDTH=600#小方格大小GRID_SIZE=20#颜色设置WHITE=(255,255,255)BLACK=(0,0,0)GREEN=(0,255,0)#初始化Pyg......
  • Python - Context Managers
    withstatementHereisthesyntaxofthewithstatement:withexpressionasvar:statementsTheexpressionshouldbeacontextmanagerobject,oritshouldproduceacontextmanagerobject.Whenthiswithstatementisexecuted,thefirstthingthat......