我是新手,我编写了一个实用程序脚本来生成一些我需要的数字.我把这个文件命名为numbers.py.该脚本依赖于PyGame库.我发现仅仅导入该库就会导致错误,因为PyGametry 从Python标准库转换为import numbers,并且默认的查找规则有我自己的文件来跟踪标准库.

我试过的短毛(皮林特,拉夫)似乎没有抓住我这个新秀的错误,但我很难理解如何最好地避免它.据我所知,"只需重命名文件"以避免与标准库冲突的建议需要以下两种之一:

  1. 记住307个标准库名称(没有句点;总共1027个名称),或者
  2. 能够通过来自其他库的错误来识别,也许你不小心隐藏了一个库,所以你可以重命名

我希望有一个更好的解决方案,比如区分标准库和本地文件的#include <foo>vs#include "foo",或者检测我创建的文件何时隐藏在标准库中的lint配置.

我如何在前进的过程中避免这个问题?

phrogz:~/proj/ai$ ls
numbers.py

phrogz:~/proj/ai$ cat numbers.py 
import pygame

phrogz:~/proj/ai$ python numbers.py
Traceback (most recent call last):
  File "/home/phrogz/proj/ai/numbers.py", line 1, in <module>
    import pygame
  File "/home/phrogz/.local/lib/python3.11/site-packages/pygame/__init__.py", line 264, in <module>
    import pygame.surfarray
  File "/home/phrogz/.local/lib/python3.11/site-packages/pygame/surfarray.py", line 47, in <module>
    import numpy
  File "/home/phrogz/.local/lib/python3.11/site-packages/numpy/__init__.py", line 130, in <module>
    from numpy.__config__ import show as show_config
  File "/home/phrogz/.local/lib/python3.11/site-packages/numpy/__config__.py", line 4, in <module>
    from numpy.core._multiarray_umath import (
  File "/home/phrogz/.local/lib/python3.11/site-packages/numpy/core/__init__.py", line 72, in <module>
    from . import numerictypes as nt
  File "/home/phrogz/.local/lib/python3.11/site-packages/numpy/core/numerictypes.py", line 595, in <module>
    _register_types()
  File "/home/phrogz/.local/lib/python3.11/site-packages/numpy/core/numerictypes.py", line 590, in _register_types
    numbers.Integral.register(integer)
    ^^^^^^^^^^^^^^^^
AttributeError: module 'numbers' has no attribute 'Integral'

推荐答案

这个问题的发生是因为

python myscript.py

myscript.py的目录得到prependedsys.path.前置意味着您自己的模块可以通过IMPORT语句before找到任何库模块.

由于这是一个"特性"(对stdlib进行monkeypatch的能力),因此它不太可能在短期内发生变化,但Python3.11+确实提供了在command-line optionsenvironment variables中退出这种潜在不安全行为的方法:

-P

不要将可能不安全的路径前置为sys.path:

  • python -m module命令行:不要在当前工作目录前面加上前缀.
  • python script.py命令行:不要预先考虑脚本的目录.如果是符号链接,则解析符号链接.
  • python -c codepython(REPL)命令行:不要在前面加上空字符串,这意味着当前的工作目录.

PYTHONSAFEPATH环境变量

这确保只有stdlib和安装的模块被import提取,并避免无意或恶意地用本地(通常是用户可写的)目录中的模块来跟踪模块.

参考文献:https://github.com/python/cpython/pull/31542

Python相关问答推荐

Python:在类对象内的字典中更改所有键的索引,而不是仅更改一个键

pandas DataFrame GroupBy.diff函数的意外输出

韦尔福德方差与Numpy方差不同

对某些列的总数进行民意调查,但不单独列出每列

运行Python脚本时,用作命令行参数的SON文本

为什么默认情况下所有Python类都是可调用的?

Stacked bar chart from billrame

无法在Docker内部运行Python的Matlab SDK模块,但本地没有问题

如何在UserSerializer中添加显式字段?

如果满足某些条件,则用另一个数据帧列中的值填充空数据帧或数组

实现神经网络代码时的TypeError

如何禁用FastAPI应用程序的Swagger UI autodoc中的application/json?

如何在PySide/Qt QColumbnView中删除列

使用Python从rotowire中抓取MLB每日阵容

从旋转的DF查询非NaN值

将一个双框爆炸到另一个双框的范围内

Beautifulsoup:遍历一个列表,从a到z,并解析数据,以便将其存储在pdf中.

如何在Python中从html页面中提取html链接?

启动线程时,Python键盘模块冻结/不工作

迭代工具组合不会输出大于3的序列