从python包资源中提取文件夹

从python包资源中提取文件夹,python,file,package,Python,File,Package,在我试图分发的包的本地版本中,我有以下代码: shutil.copytree(WWW_LOCATION, dir_path) WWW\u LOCATION是my python模块的一个子文件夹,包含一些静态文件和文件夹: dv \dv mytool.py \www_folder \somefolders_and_files setup.py MANIFEST.in README.md LICENSE setup.cfg 在我的代码中,

在我试图分发的包的本地版本中,我有以下代码:

shutil.copytree(WWW_LOCATION, dir_path)
WWW\u LOCATION
是my python模块的一个子文件夹,包含一些静态文件和文件夹:

dv
  \dv
     mytool.py
     \www_folder
       \somefolders_and_files
  setup.py
  MANIFEST.in
  README.md
  LICENSE
  setup.cfg
在我的代码中,在执行之后,我需要将整个文件夹与一些动态生成的文件一起复制到用户指定的位置。这在本地非常有效,但我了解到,对于通过pypi进行分发,我必须小心,因为文件可能会被压缩


解释如何访问资源中的内容(=在python中读取),但是一次只能访问一个文件。将文件夹内容复制到指定位置的安全方法是什么

更简单的解决方案是在软件包设置中设置
zip\u safe=False
setup.py
setup.cfg
),以避免将软件包作为压缩鸡蛋安装。由于大多数安装都是通过
pip
完成的,而pip从来不会创建压缩鸡蛋安装,因此现在运行压缩包安装就更为罕见了

然后,您只需担心有人手动将包压缩到zipfile中以添加到
sys.path
,您可以选择不支持这种用例。这是一种不同形式的拉链包装;鸡蛋是一个可安装项目的ZipFile(由
pkg_resources
支持),并将它们存储在
sys.path
上列出的目录中
pkg_资源
只能支持后者,不能支持前者

如果您确实希望支持压缩鸡蛋,那么对于您的特定情况,它将更易于使用,因为虽然它可能“较慢”,但它还支持完整的目录树。从
资源\u filename()
文档中:

如果命名的资源是一个目录,那么该目录中的所有资源(包括子目录)也将被提取

我会这样使用它:

try:
    www_location = pkg_resources.resource_filename("dv", "www_folder")
    shutil.copytree(www_location, dir_path)
finally:
    pkg_resources.cleanup_resources()
在直接添加到
sys.path的zipfile中找到的包内资源无法通过
pkg\u资源访问。为此,您需要更新的(或它的),但此API不支持任意目录结构。各国:

包是符合
要求的名称或模块对象。resource是要在包中打开的资源的名称;它可能不包含路径分隔符,也可能没有子资源(即它不能是目录)

(我的粗体强调)

虽然您可以使用查找包中的目录,但您实际上无法访问这些目录的内容,除非它们本身是Python包(因此在它们中有一个
\uuuu init\uuuuuuuuuuy.py
文件)。在使用
importlib.resources.path()
时,为传统的非压缩包实现这些功能仍将允许您访问目录,但当包包含在
.zip
存档中时,您不能执行相同的操作


importlib.resources
是一种更好、经得起未来考验的支持途径。为了支持这一点,您可以在源代码和控制盘发行版中压缩
www\u文件夹
资源树,然后将
与importlib.resources.path(“dv”、“www\u folder.zip”)一起用作www\u位置:www\u zip=zipfile.open(www\u位置)
并将该zipfile对象的内容提取到目的地。

感谢您发表的大量文章-我决定使用
zip\u safe=False
,因为在这种情况下,资源文件仅为60kb,因此不需要压缩它们。