Python 和 py2exe - 隐式导入模块

发布于 2024-12-28 14:13:24 字数 2127 浏览 1 评论 0原文

我过去曾多次使用 py2exe 为我的 python 程序创建 *.exe 文件。但是,这次我遇到了错误。我想我知道问题是什么,但我不知道如何解决。

我的子文件夹中有一些 wx.Panels,它的数量可能是可变的,因此我通过一个函数导入它们,该函数查找文件夹中的 *.py 文件并调用下面的函数来实际导入每个面板。

在普通的 python 中,这工作得很好。然而,py2exe 忽略了这些文件。我认为因为它们没有显式导入,所以 py2exe 认为不需要它们。有解决办法吗? py2exe 中的一些我不知道的选项?

谢谢!

# module = Module to be imported (string)
# folder = Folder containing the module (string)
def import_module(module, folder=None):
   if folder is None:
      return __import__(module)
   return getattr(__import__('%s.%s' % (folder.replace(os.path.sep, '.'),
      module)), module)


...within some other function...
modules = [import_module(os.path.basename(os.path.splitext(filename)[0]), 'Panels') for filename in glob.glob('Panels//*.py')]

编辑

我正在添加我使用过的示例 setup.py 脚本。但我使用了大约 20 种不同的变体和几个完全不同的脚本(我可以在互联网上找到)。请注意,一项要求是它完全独立于一个可执行文件中。

from distutils.core import setup
import py2exe

import wxversion
wxversion.select("2.8.12.1")
import wx
import wx.lib.pubsub

includes = []
excludes = ['_gtkagg', '_tkagg', 'bsddb', 'curses', 'email', 'pywin.debugger',
            'pywin.debugger.dbgcon', 'pywin.dialogs', 'tcl',
            'Tkconstants', 'Tkinter']
packages = ['wx.lib.pubsub']
dll_excludes = ['libgdk-win32-2.0-0.dll', 'libgobject-2.0-0.dll', 'tcl84.dll',
                'tk84.dll']

import glob
my_data_files = [('Panels', glob.glob('Panels/*.py'))]

setup(
    options = {"py2exe": {"compressed": 2,
                          "optimize": 2,
                          "includes": includes,
                          "excludes": excludes,
                          "packages": packages,
                          "dll_excludes": dll_excludes,
                          "bundle_files": 2,
                          "dist_dir": "dist",
                          "xref": False,
                          "skip_archive": False,
                          "ascii": False,
                          "custom_boot_script": '',
                         }
              },
    zipfile = None,
    #data_files = my_data_files,
    windows=['Main.py']
)

I've used py2exe several times in the past to create *.exe files for my python programs. However, I'm getting an error this time. I think I know what the issue is, but I don't know how to resolve it.

I have a handful of wx.Panels in a subfolder and it could be a variable amount, so I import them via a function that finds the *.py files in the folder and calls the function below to actually import each panel.

In normal python, this works well. However, py2exe leaves these files out. I assume that because they are not explicitly imported, py2exe doesn't believe they are needed. Is there a solution to this? Some option in py2exe that I'm unaware of?

Thanks!

# module = Module to be imported (string)
# folder = Folder containing the module (string)
def import_module(module, folder=None):
   if folder is None:
      return __import__(module)
   return getattr(__import__('%s.%s' % (folder.replace(os.path.sep, '.'),
      module)), module)


...within some other function...
modules = [import_module(os.path.basename(os.path.splitext(filename)[0]), 'Panels') for filename in glob.glob('Panels//*.py')]

EDIT

I'm adding a sample setup.py script I've used. But I've used probably 20 different variations and several completely different scripts (what I could find on the internet). Note that one requirement is that it is completely self-contained in one executable file.

from distutils.core import setup
import py2exe

import wxversion
wxversion.select("2.8.12.1")
import wx
import wx.lib.pubsub

includes = []
excludes = ['_gtkagg', '_tkagg', 'bsddb', 'curses', 'email', 'pywin.debugger',
            'pywin.debugger.dbgcon', 'pywin.dialogs', 'tcl',
            'Tkconstants', 'Tkinter']
packages = ['wx.lib.pubsub']
dll_excludes = ['libgdk-win32-2.0-0.dll', 'libgobject-2.0-0.dll', 'tcl84.dll',
                'tk84.dll']

import glob
my_data_files = [('Panels', glob.glob('Panels/*.py'))]

setup(
    options = {"py2exe": {"compressed": 2,
                          "optimize": 2,
                          "includes": includes,
                          "excludes": excludes,
                          "packages": packages,
                          "dll_excludes": dll_excludes,
                          "bundle_files": 2,
                          "dist_dir": "dist",
                          "xref": False,
                          "skip_archive": False,
                          "ascii": False,
                          "custom_boot_script": '',
                         }
              },
    zipfile = None,
    #data_files = my_data_files,
    windows=['Main.py']
)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

吝吻 2025-01-04 14:13:24

我相信我已经找到了解决我的问题的方法。在我的 setup.py 文件中,我将 'includes = []' 行替换为:

includes = ['Panels.%s' % os.path.basename(os.path.splitext(filename)[0]) for
        filename in glob.glob('Panels//*.py')]

在我使用 'import_module' 函数的代码中,它曾经使用该 glob 来导入 Panels 目录中的模块。相反,我硬编码了要包含的模块列表。

这不是我想要的确切解决方案(我不想对面板列表进行硬编码),但它似乎确实有效。除非我发现更好的东西,否则我将继续使用它。

I believe I've found the solution for my issue. In my setup.py file, I replaced the 'includes = []' line with:

includes = ['Panels.%s' % os.path.basename(os.path.splitext(filename)[0]) for
        filename in glob.glob('Panels//*.py')]

In my code where I use the 'import_module' function, it used to use that glob to import the modules within the Panels directory. Instead, I've hard-coded a list of modules to include.

This isn't the exact solution I wanted (I don't want to hard-code that list of panels), but it does seem to work. Unless I discover anything better, this is what I'll continue to use.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文