问题

python setup.py data_files 设置要拷贝的文件,不能拷贝到安装目录下。要怎样解决?

回答
在 Python 包的构建过程中,`setup.py` 中的 `data_files` 参数是一个非常常用的功能,用于将数据文件(如配置文件、资源文件、模板等)一起打包并安装到目标环境中。然而,有时候我们会遇到一个令人困扰的问题:`data_files` 设置的文件似乎无法被正确地安装到我们预期的位置,尤其是当你想将它们安装到 Python 的sitepackages 目录下的某个子目录中时。

下面我将详细解释 `data_files` 的工作原理,分析为什么它可能“看起来”没有拷贝到安装目录下,并提供几种有效的解决方案,帮助你将数据文件准确地放置在你需要的位置。

理解 `setup.py` 和 `data_files`

在深入问题之前,我们先回顾一下 `setup.py` 和 `data_files` 的基本概念。

`setup.py`: 这是 Python 包的“心脏”。它使用 `setuptools`(或者曾经的 `distutils`)库来定义你的包的元数据(名称、版本、作者等)以及如何构建和安装你的包。当你运行 `python setup.py install` 或 `pip install .` 时,`setup.py` 文件会被执行。

`data_files`: 这是 `setup()` 函数的一个参数,它是一个列表。列表中的每个元素也是一个元组 `(destination, sources)`。
`destination`: 指定文件要安装到的目标目录。这个路径是相对于 Python 的安装前缀(`prefix`)或者安装脚本目录(`scripts`)来解析的。
`sources`: 指定要复制到 `destination` 的文件或目录列表。这些文件可以是相对路径(相对于 `setup.py` 文件)或者绝对路径。

举个例子:

```python
from setuptools import setup, find_packages

setup(
name='my_package',
version='0.1.0',
packages=find_packages(),
data_files=[
('config', ['my_config.ini', 'templates/template.html']),
('/usr/share/my_package/data', ['data/my_data.json']) 注意这里的绝对路径例子
],
... 其他参数
)
```

在这个例子中:
`('config', ['my_config.ini', 'templates/template.html'])` 意味着 `my_config.ini` 和 `templates/template.html` 会被安装到 `/config` 目录下。
`('/usr/share/my_package/data', ['data/my_data.json'])` 意味着 `my_data.json` 会被安装到 `/usr/share/my_package/data` 目录下。

为什么 `data_files` 看起来没拷贝到安装目录下?

“没有拷贝到安装目录下”通常不是 `data_files` 本身的问题,而是我们对“安装目录”的理解,或者 `data_files` 参数的用法存在一些误解。

1. 相对路径解析的误解:
`data_files` 中的 `destination` 路径是相对于 Python 安装前缀 (`sys.prefix`) 来解析的。在标准的 Python 安装中,这通常是你的虚拟环境的根目录,或者系统 Python 的安装位置。
如果你期望文件安装到 `sitepackages` 目录下(例如,`my_package/data/my_data.json`),直接使用 `('sitepackages/my_package/data', ...)` 是不正确的。`sitepackages` 本身就是一个目录,你只需要指定它后面的相对路径。
正确的做法应该是 `('my_package/data', ...)`。`setuptools` 会自动找到 `sitepackages` 的位置,并在其下创建 `my_package/data` 目录。

2. `package_data` 和 `data_files` 的混淆:
`data_files` 用于安装任意文件到任意目录。
`package_data` 则用于安装随 Python 包本身一起分发的数据文件。这些文件会安装到你的包的目录结构中(例如,`my_package/data/my_data.json`)。这通常是我们最常见的需求:将数据文件与代码模块放在一起。
如果你想把数据文件放在你的包目录内部,那么 `package_data` 通常是更合适的选择。

3. 安装前缀 (`prefix`) 的影响:
如果你使用的是虚拟环境(如 venv, conda),那么 Python 的安装前缀就是那个虚拟环境的根目录。
如果你是在系统环境中安装,前缀可能是 `/usr/local` 或其他位置。
`data_files` 中的目标路径会附加到这个前缀上。

4. 执行 `setup.py` 的方式:
确保你是在包含 `setup.py` 的项目根目录下执行安装命令,例如 `pip install .` 或 `python setup.py install`。
在开发模式下安装 (`pip install e .`),文件可能会以链接的形式存在,而不是直接复制,这可能会让你觉得它们“没有被拷贝”。

解决办法:如何将文件准确地拷贝到安装目录?

下面是几种常见的场景和对应的解决方案:

场景 1: 将数据文件随包一起安装到包的子目录中

这是最常见和推荐的做法。你想让你的数据文件(如模板、配置文件样本、资源)与你的 Python 代码模块紧密关联,例如 `my_package/data/config.json`。

解决方案:使用 `package_data`

`package_data` 是专门为这种情况设计的。它指定了哪些数据文件应该包含在你的包内,并且会与包一起被复制到 `sitepackages`。

```python
from setuptools import setup, find_packages

setup(
name='my_package',
version='0.1.0',
packages=find_packages(), 自动查找包含 __init__.py 的目录
package_data={
'my_package' 是包的名称(即 __init__.py 所在的目录名)
'' 是通配符,匹配所有文件
'' 是递归通配符,匹配所有子目录和文件
'my_package': ['data/.json', 'templates/.html'],
如果你的包有多个子包,例如 my_package.sub_package
'my_package.sub_package': ['data/config.yaml']
},
include_package_data=True, 告诉 setuptools 包含 package_data 指定的文件
... 其他参数
)
```

说明:

`packages=find_packages()`: 这是一个很好的实践,它会自动发现你项目中的所有 Python 包(即包含 `__init__.py` 的目录)。
`package_data={'my_package': [...]}`: 这里你指定了包名 `my_package`,以及它应该包含的数据文件模式。
`'data/.json'`: 表示 `my_package/data/` 目录下的所有 `.json` 文件。
`'templates/.html'`: 表示 `my_package/templates/` 目录下的所有 `.html` 文件。
你可以使用更复杂的 glob 模式,例如 `'data/'` 来包含 `data` 目录下的所有文件和子目录。
`include_package_data=True`: 非常重要!这个参数必须设置为 `True`,否则 `package_data` 中的设置会被忽略。

文件结构示例:

```
my_package_project/
├── setup.py
├── my_package/
│ ├── __init__.py
│ ├── module.py
│ ├── data/
│ │ └── config.json
│ └── templates/
│ └── template.html
└── README.md
```

当你执行 `pip install .` 后,你的包结构会是这样:

```
your_venv/lib/pythonX.Y/sitepackages/
├── my_package/
│ ├── __init__.py
│ ├── module.py
│ ├── data/
│ │ └── config.json < 文件在此
│ └── templates/
│ └── template.html < 文件在此
└── my_package0.1.0.distinfo/
└── ...
```

如何访问这些文件:

在你的代码中,你可以使用相对路径来访问这些文件:

```python
import os

获取当前模块文件所在的目录
package_dir = os.path.dirname(__file__)
config_path = os.path.join(package_dir, 'data', 'config.json')
template_path = os.path.join(package_dir, 'templates', 'template.html')

with open(config_path, 'r') as f:
config_data = f.read()
```

场景 2: 将数据文件安装到 Python 的安装前缀下的某个特定目录(非包目录)

你可能希望将一些全局配置文件、二进制文件或者数据文件安装到 Python 环境的某个标准位置,而不是随特定包一起。例如,你想把一个配置文件安装到 `sys.prefix/etc/my_package/`。

解决方案:使用 `data_files` 和正确的 `destination`

正如前面提到的,`data_files` 的 `destination` 是相对于 `sys.prefix` 的。

```python
import sys
from setuptools import setup, find_packages

sys.prefix 是 Python 安装的根目录(通常是虚拟环境的根目录)
例如:/path/to/your/venv
或者:/usr/local

如果你想安装到 /etc/my_package/
那么 destination 就是 'etc/my_package'
config_destination = 'etc/my_package'
data_destination = 'share/my_package/data' 另一个例子

setup(
name='my_package',
version='0.1.0',
packages=find_packages(),
data_files=[
第一个参数是目标目录,相对于 sys.prefix
第二个参数是要复制的文件列表,路径相对于 setup.py
(config_destination, ['config/my_app.conf', 'config/logging.conf']),
(data_destination, ['data/lookup.dat']),
你也可以安装脚本文件到 scripts 目录,通常是 /bin
('', ['bin/my_script.py']) 这种方式会安装到 sys.prefix/bin
],
注意: 如果你的数据文件位于包目录内,并且与包代码紧密相关,
强烈建议使用 package_data 替代 data_files。
data_files 更适合安装独立于包结构的文件。

... 其他参数
)
```

文件结构示例:

```
my_package_project/
├── setup.py
├── my_package/
│ ├── __init__.py
│ └── module.py
├── config/
│ ├── my_app.conf
│ └── logging.conf
├── data/
│ └── lookup.dat
└── README.md
```

当你执行 `pip install .`(在虚拟环境中)后,文件会被安装到:

```
your_venv/
├── bin/
│ └── ...
├── etc/
│ └── my_package/
│ ├── my_app.conf < 文件在此
│ └── logging.conf < 文件在此
├── lib/
│ └── pythonX.Y/
│ └── sitepackages/
│ ├── my_package/
│ │ ├── __init__.py
│ │ └── module.py
│ └── my_package0.1.0.distinfo/
│ └── ...
└── share/
└── my_package/
└── data/
└── lookup.dat < 文件在此
```

如何访问这些文件:

在你的代码中,你需要知道 `sys.prefix` 的位置,或者使用 `sysconfig` 模块来获取更准确的安装目录信息。

```python
import sys
import os

假设你知道数据文件被安装到了 sys.prefix 下的 'share/my_package/data'
这种方式比较硬编码,不灵活。
config_path = os.path.join(sys.prefix, 'etc', 'my_package', 'my_app.conf')

更推荐的方式是让你的包提供一个函数来查找这些资源
def get_config_path(filename):
获取包含 my_package/__init__.py 的目录的父目录,然后在其下寻找配置
这依赖于你的包结构,如果包是这样安装的:
sitepackages/my_package/
它就不适合了。

对于 data_files 安装到 sys.prefix 的情况,
你需要更明确地知道安装路径,或者通过一个专门的函数来查找
例如,我们可以假定一个约定:在包的根目录下提供一个函数来查找资源
或者,更可靠的是,将这些文件安装到 sitepackages/my_package/data 目录,
然后使用 package_data。

如果你确实需要访问 data_files 安装的文件,一种方式是查找某个标记文件
或者直接构建路径(假设你知道 sys.prefix 的结构)
更好的做法是,如果你在包的某个地方需要访问这些文件,
在安装时就把它们的绝对路径告诉你的包的某个配置项。

以下是一个“尝试”找到文件的例子,但可能不够鲁棒
更好的方法是通过 get_data 函数 (如果你使用 setuptools_scm 或类似工具)
或者提供一个查找函数
pass

如果你将文件安装到 sitepackages/my_package/config
并且使用了 package_data
from . import data
config_path = os.path.join(os.path.dirname(data.__file__), 'config.json')

如果你坚持使用 data_files,并且想访问那些非包目录的文件,
那么通常你的包在初始化时会去查找它们,或者提供一个配置加载器
比如在 my_package/__init__.py 中:
def find_config_file(filename):
base_dir = sys.prefix 或者更精确地使用 sysconfig
return os.path.join(base_dir, 'etc', 'my_package', filename)
```

重要提示关于 `data_files`:

Python 3.5+: `data_files` 在 Python 3.5+ 中被认为是“过时”的,并且在未来的版本中可能会被移除。尽管如此,它仍然在广泛使用。
跨平台兼容性: 使用硬编码的绝对路径(如 `/usr/share/my_package`)在 Windows 上会遇到问题。`setuptools` 会尝试将这些路径与 `sys.prefix` 或 `sysconfig` 的值结合,以生成一个相对更兼容的路径。但即使这样,`data_files` 的跨平台行为有时也会有些微妙。
推荐: 如果你的数据文件是包的一部分,应该使用 `package_data`。如果你需要安装全局配置文件,考虑使用操作系统的包管理器(如 apt, yum, brew)或者专门的配置管理工具,或者至少提供一个灵活的查找机制(例如,允许用户通过环境变量指定配置文件的位置)。

场景 3: 将 Python 脚本作为可执行文件安装

如果你有一个 Python 脚本,希望用户在安装你的包后,可以直接在命令行运行它。

解决方案:使用 `scripts` 参数

```python
from setuptools import setup, find_packages

setup(
name='my_package',
version='0.1.0',
packages=find_packages(),
scripts=['bin/my_command'], 指向你的脚本文件
data_files=[...],
package_data={...},
...
)
```

说明:

`scripts=['bin/my_command']`: 这个参数会将 `bin/my_command` 文件复制到 Python 环境的 `bin` 目录(通常是 `sys.prefix/bin`),并根据需要添加 Shebang 线(`!/usr/bin/env python`)或 `.exe` 后缀(在 Windows 上)。

当你执行 `pip install .` 后,`your_venv/bin/my_command`(或者 `your_venv/Scripts/my_command.exe` 在 Windows)就会被创建,用户可以直接运行 `my_command`。

总结与建议

1. 优先使用 `package_data`: 如果数据文件是你的 Python 包的组成部分,并且需要随包一起分发和加载,那么 `package_data` 是最清晰、最推荐的方式。它能确保文件被安装到你的包的目录结构中,易于通过相对路径访问。
2. `data_files` 的谨慎使用: 当你需要安装独立于包目录结构的文件时才考虑使用 `data_files`。理解 `destination` 是相对于 `sys.prefix` 的。对于跨平台兼容性和可维护性,要格外小心。
3. 测试你的安装: 在不同的操作系统和 Python 环境中测试你的安装过程,确保 `data_files` 和 `package_data` 中的文件被正确放置。
4. 查找资源: 如果你的包需要访问安装的数据文件,最佳实践是在你的包的代码中提供一个函数来定位这些文件,而不是让用户去猜测它们安装在哪里。例如,你可以让 `setup.py` 将一个包含文件路径的配置文件安装到包目录,或者提供一个查找机制。

通过正确理解 `package_data` 和 `data_files` 的用途和行为,你就能更有效地将你的数据文件打包到你的 Python 分发版中,并确保它们能够被正确地安装和访问。

网友意见

user avatar

最近恰巧也遇到了这个问题,网上貌似没有完整详细的解答。解释一下我对题主的意思的理解:在使用python的setup.py将项目打包成wheel时,需要打包项目外的静态文件,但是无论setup的data_files参数如何设置,打包得到的轮子在安装后,静态文件都无法自动存储于该库的安装目录下。这其实是由于setup打包轮子的脚本不鼓励绝对路径,而相对路径是基于sys.prefix的。所以想要自动存储在安装目录下,可以死了这条心了。

王炳明:花了两天,终于把 Python 的 setup.py 给整明白了 这篇文章是我在全网看到的对setuptool讲解最为细致全面的,但是当然它没有提到题主的问题。下面我详细解释一下data_files参数,也作为一个学习的记录。

静态文件是什么

这里指的是除去*.py文件以外的其他类型的文件。我尝试过将包含图片和网页文件的文件夹作为package进行打包,企图通过这种方式把静态文件包含在轮子里。事实证明轮子安装后这个文件夹下只有_init_.py一个文件。在打包时,我们一般把静态文件综合起来放在top-level的package外面,即和setup.py同级目录下。

两种静态文件打包方法

在打包egg、tar.gz等格式时,编写MANIFEST.in将静态文件的路径include进来,注意这里的语法支持通配符,参考Python打包时包含静态文件处理方法。相关文章很多,大多互相抄袭而且不给引用,强烈谴责,因为我也找不到最早的原创了,在此引一篇还算清晰的。

在打包whl格式时,不需编写MANIFEST.in,而是通过data_files参数将静态文件路径包含进来,并指定安装时的存储位置。在3.1版本之后的setup中,不设置模板文件MANIFEST.in时,会将data_files中的文件自动添加到MANIFEST中。提一下另外一位答主的答案,的确可以不使用sdist参数来打包,但是对于必须使用whl格式的场景,这个问题是绕不开的,毕竟轮子现在是python的官方标准二进制文件,并且在pypi上发布时也需要。

data_files参数详解

参考官方文档2. Writing the Setup Script,以下是我的翻译和注解。

data_files参数可以用于指定模块发布所需的额外文件:配置文件、信息目录、数据文件和其他前文没有提到的文件类型。文档中前文提到了包数据文件*.dat,编写python语言扩展模块时可能用到的*.c和*.i。

data_files按照下面例子中给出的方式指定了一个(directory, files)对儿的列表。

       setup(..., data_files=[     ('bitmaps', ['bm/b1.gif', 'bm/b2.gif']),      ('config',  ['cfg/data.cfg']) ],)     

每一个(directory, files)对儿指定了安装时文件的存储路径,和文件目前存储的位置。

后者files是相对于setup.py脚本的相对路径。注意你可以指定安装时存储的路径,却不能在安装时自动给文件重命名。files中文件夹的名字不会影响安装时路径的命名,这里只关心文件的名字。

前者directory的安装存储路径同样应为相对路径,它相对于安装前缀(系统级安装时为sys.prefix,用户级安装时为site.USER_BASE,我们一般都是系统级安装。)Distutil在最上面引用的那篇文章中有提到,是setup的前身,支持绝对路径,但是在打包轮子的脚本里面故意去掉了这个支持。这种改进的用心其实很好理解,你可以输出这几个路径观察一下,我的电脑上是这样的:

       >>> import sys >>> sys.prefix '/Users/liushangyu/opt/anaconda3' >>> sys.exec_prefix '/Users/liushangyu/opt/anaconda3' >>> get_python_lib() '/Users/liushangyu/opt/anaconda3/lib/python3.8/site-packages'     

题主肯定是和我最初一样希望静态文件能随着库文件夹都安装在get_python_lib()的路径下,但是不同用户的python版本不同,安装路径也可能不同,就无法确定这个前缀lib/python3.8/site-packages中的python3.8具体是多少了。为了安装时的兼容性,我们当然不能设置绝对路径。

我试验设置绝对路径,setup将我的绝对路径拼接在get_python_lib()路径后面得到一个超级深的目录;我试验设置相对路径前面加上/,因为怀疑绝对路径是由于有/而导致的,结果路径无法解析;我试验拼接上get_python_lib()减去sys.prefix的那部分,结果又拼接到了get_python_lib()上面;只有在直接设置一个和get_python_lib()中的路径不重合的相对路径时,是拼接到sys.prefix上面的。

这个问题在Github的issue中也有讨论:bdist_wheel makes absolute data_files relative to site-packages。我不知道目前与更高版本的python兼容的setuptool是否有更高版本,我的一个朋友发布时用的是Python3.9环境下的绝对路径,我不知道他怎么成功的。

类似的话题

  • 回答
    在 Python 包的构建过程中,`setup.py` 中的 `data_files` 参数是一个非常常用的功能,用于将数据文件(如配置文件、资源文件、模板等)一起打包并安装到目标环境中。然而,有时候我们会遇到一个令人困扰的问题:`data_files` 设置的文件似乎无法被正确地安装到我们预期的位.............
  • 回答
    Python 作为一种强大的数据科学语言,拥有丰富多样的数据可视化库,为用户提供了从基础绘图到复杂交互式可视化的广泛选择。除了 `matplotlib` 这个被誉为“万能瑞士军刀”的库之外,还有许多其他优秀的库,它们在特定领域、易用性、交互性或美学风格上各有千秋。下面我将详细介绍一些常用的 Pyth.............
  • 回答
    处理百亿行、数十列的数据是一项巨大的挑战,它不仅仅是简单地将数据加载到内存中,而需要一套系统性的策略来克服内存限制、提高处理效率和保证计算的稳定性。Python/Pandas本身在内存受限的情况下处理如此大规模的数据会遇到困难,但我们可以结合Pandas与其他工具和技术来应对。下面将详细讲解Pyth.............
  • 回答
    Python 是一门功能强大且用途广泛的语言,有很多很棒的练手项目可以帮助你学习和巩固知识。我会根据不同的学习阶段和兴趣方向,为你推荐一些值得详细介绍的项目,并说明为什么它们是好的练手项目。在开始之前,你需要具备的基础: Python 基础语法: 变量、数据类型(整型、浮点型、字符串、列表、元组.............
  • 回答
    Python 绝对是一门对面向对象编程 (OOP) 非常友好的语言,并且在很多方面都做得非常出色,让 OOP 的实践变得直观、简洁且强大。但正如所有技术一样,总有改进的空间。下面我将详细阐述 Python 在 OOP 方面的友好性,以及它可能存在的改进空间: Python 对面向对象编程的友好性体现.............
  • 回答
    Python 语言的强制缩进,也就是“代码块”的定义完全依赖于缩进,而不是像许多其他语言那样使用花括号 `{}` 或 `begin/end` 等关键字,这是一个在开发者社区中长期存在争议的话题。 是否是“败笔”,很大程度上取决于个人的编程习惯、对代码可读性的侧重以及所处的开发环境。下面我将详细阐述支.............
  • 回答
    Python 2 和 Python 3 之间存在许多重要的区别,这些区别使得 Python 3 更现代化、更易于使用、更强大。以下是一些主要的区别,我会尽可能详细地解释: 1. `print` 语句与 `print()` 函数Python 2: `print` 是一个语句(statement)。``.............
  • 回答
    Python 在变量的定义和赋值方面,确实与一些其他静态类型语言(例如 C++、Java)存在显著差异,这种差异常常被一些开发者看作是 Python 设计上的一个特点,但将其直接定义为“设计上的缺陷”则需要更深入的分析。要理解这个问题,我们首先需要明确 Python 在变量处理上的核心机制:Pyth.............
  • 回答
    Python 的标准库和第三方库非常丰富,覆盖了从基础操作到复杂应用的各个领域。以下是对这些库的详细分类和介绍,帮助你了解它们的用途和使用场景: 一、Python 标准库(内置模块)Python 的标准库是随 Python 解释器一同安装的,无需额外安装即可使用。以下是常见的分类和示例: 1. 基础.............
  • 回答
    Python 的“黑魔法”通常指的是一些不常见、非传统、或者需要深入理解 Python 底层机制才能掌握的技巧。它们能够让你写出更简洁、更强大、甚至有些“反直觉”的代码。这些“黑魔法”往往能极大地提高开发效率,但也可能降低代码的可读性,因此使用时需要权衡。下面我将尽量详细地介绍一些 Python 的.............
  • 回答
    这个问题嘛,就像问“我该选择披萨还是汉堡?”一样,答案很大程度上取决于你想做什么,以及你对“前景好”的定义。Python和Go,说实话,现在都处于职业生涯的黄金时期,硬要说谁“更好”,实在是个见仁见智的事。不过,咱们可以把它们俩的特点拉出来遛遛,看看哪个更对你的胃口。Python:万金油,社区的拥抱.............
  • 回答
    关于Python学习年龄这件事,我得说,这事儿挺灵活的,不像定个死规矩那样。我身边就有不少朋友,年龄跨度挺大的,都有自己的收获。如果你是还在学校的学生(小学、初中、高中): 小学阶段: 我觉得这得看孩子的兴趣和家长引导了。如果孩子本身就对电脑操作、小游戏制作、或者一些逻辑思维的游戏比较感兴趣,那.............
  • 回答
    在 Python 中,`with ... as ...` 语句主要用于资源管理,特别是文件的打开和关闭,或者其他需要进行清理操作的对象。它的核心目的是 确保无论代码块如何退出(正常结束、抛出异常),都会执行清理操作。如何理解 "跳出" `with...as` 语句?这里的“跳出”可以从两个层面来理解.............
  • 回答
    没问题,我来给你详细讲讲如何在 Python 中实现“按分类转换列表”。这个需求很常见,比如我们有一个包含各种类型数据的列表,我们想根据数据的类型把它们分成不同的子列表。咱们就用一个实际的例子来讲解,这样更容易理解。假设我们有一个混合类型的列表,里面有数字、字符串、布尔值等等,我们想把它们分别归类到.............
  • 回答
    在 Python 中,`len(x)` 并不是一个用于补零的函数,它实际上是用来获取序列(如字符串、列表、元组等)长度的。你提到的“利用 `len(x)` 补零”可能是在说,你需要根据某个序列的长度,将另一个序列(通常是数字或字符串)进行补零操作,使其达到一个特定的长度。核心概念:为什么是补零?补零.............
  • 回答
    好的,我们来聊聊如何用Python实现列表(list)中所有元素两两相加并找出最大值这件事。这听起来是个挺基础的操作,但我们把它拆解开来,深入理解一下其中的逻辑和实现方式。问题拆解:首先,我们要明确这个任务包含几个关键步骤:1. 获取列表: 我们需要一个列表作为输入。2. 两两相加: 列表中的每.............
  • 回答
    Python 正则替换:让每个匹配项拥有专属身份在日常的文本处理中,我们常常需要根据文本内容的规律性进行修改。Python的正则表达式提供了强大的模式匹配能力,而`re`模块的`re.sub()`函数则是进行替换操作的核心工具。然而,当我们需要将一个正则表达式匹配到的多个不同位置替换成不同的内容时,.............
  • 回答
    Python 函数的二次封装:让你的代码更优雅、更实用在 Python 的世界里,我们常常需要利用现有的库函数来完成各种任务。然而,原生的函数虽然功能强大,但有时在使用起来可能不够灵活,或者需要额外的配置才能达到我们想要的效果。这时候,“函数二次封装”就成了提升代码质量、提高开发效率的利器。简单来说.............
  • 回答
    好的,咱们就来聊聊 Python 爬虫怎么“对付”那些藏在 `.js` 文件里的链接。这事儿吧,不像直接抓 HTML 那么简单粗暴,因为 `.js` 文件是 JavaScript 代码,它本身不会直接告诉你链接是什么,你需要去“解读”它。想象一下,你拿到一份说明书,但这份说明书是用密码写的,你需要先.............
  • 回答
    深入Python:如何优雅地“驾驭”内置类型在Python这门充满魅力的语言中,我们每天都在与各种内置类型打交道:数字、字符串、列表、字典等等。它们是我们构建程序的基石。但你是否曾想过,在某些特殊场景下,我们能不能给这些“老朋友”赋予新的能力,让它们变得更“懂事”、更贴心?答案是肯定的,Python.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有