如果我将脚本命名为“ string.py”或“ math.py”,则“导入”操作的行为会有所不同。为什么会这样呢?

时间:2019-10-11 19:35:13

标签: python python-3.x python-import built-in

已更新:

案例1:

同一文件夹中的文件:

main.py

string.py

main.py 中的代码:

import string

string.py 中的代码:

print('Hello!')

运行 main.py 的输出是:你好!

案例2:

同一文件夹中的文件:

main.py

math.py

main.py 中的代码:

import math

math.py 中的代码:

print('Hello!')

运行 main.py 输出无济于事...

旧问题:

如果我将脚本命名为'string.py'并将其导入另一个脚本,则它将与内置的'string'模块重叠

如果我将脚本命名为'math.py'并将其导入另一个脚本,则内置的'math'与我自己的脚本重叠

使用内置模块之类的名称导入脚本的行为取决于我如何命名它们。

受影响的某些模块名称:hashlib,字符串,日历

不影响的模块名称:数学,cmath,操作系统

来自realpython.com

  

Python要做的第一件事是在sys.modules中查找名称abc。   这是先前已导入的所有模块的缓存。如果   在模块缓存中找不到该名称,Python将继续   搜索内置模块列表。这些是模块   预先安装了Python,可以在Python标准中找到   图书馆。如果在内置模块中仍找不到该名称,则使用Python   然后在sys.path定义的目录列表中进行搜索。

摘自Michael Lutz的“学习Python”:

  

大致上,Python的模块搜索路径由串联组成   这些主要组件中的一部分,其中一些是为您预先设置的,另一些是   您可以定制其中的哪些内容来告诉Python查找位置:

     
      
  1. 程序的主目录

  2.   
  3. PYTHONPATH目录(如果已设置)

  4.   
  5. 标准库目录

  6.   
  7. 任何.pth文件的内容(如果存在)

  8.   
  9. 该站点将第三方扩展程序打包到首页

  10.   

那现在哪个是正确的?

2 个答案:

答案 0 :(得分:2)

数学和字符串之间的区别在于,数学是用C语言编写的,以提高速度,而字符串模块是用Python编写的,可以在python lib目录下找到。

因此,当您尝试导入字符串时,本地文件将覆盖全局字符串文件,但是当您尝试导入数学时,Python不会搜索文件,因为它是内置在Python解释器中的。

您可以使用以下代码找到所有内置模块的列表:

import sys
print(sys.builtin_module_names)

如果您真的想覆盖数学模块,可以通过更改sys.modules字典中的值来实现。

答案 1 :(得分:1)

我不认为@ZacharyaHaitin的答案是正确的,而且我非常确定,如果Karen确实看到问题中描述的行为,那么肯定还有其他事情在发生。

让我们看一些例子...

覆盖string模块

我们有一个空目录,其中包含两个文件:

$ ls
main.py string.py

文件main.py包含:

$ cat main.py
import string

文件string.py包含:

$ cat math.py
print('hello')

运行main.py时,我们看到:

$ python main.py
hello

覆盖math模块

如果我们对math执行相同的实验,则会看到相同的行为。这是main.py

$ cat main.py
import math

这是math.py

$ cat math.py
print('hello')

运行main.py时,我们看到的行为与上例相同:

$ python main.py
hello

以上示例在Python2和Python3中的行为相同。在两种情况下,都不必与sys.modules混为一谈。


以下是一个脚本,将重现以上示例:

#!/bin/sh

echo "Overriding string module"

cat > main.py << EOF
import string
EOF

cat > string.py <<EOF
print('hello')
EOF

echo "main.py"
echo "-------"
cat main.py
echo

echo "string.py"
echo "---------"
echo
cat string.py
echo

echo "Running main.py..."
python main.py

cat <<EOF

======================================================================

EOF

echo "Overriding math module"

cat > main.py << EOF
import math
EOF

cat > math.py <<EOF
print('hello')
EOF

echo "main.py"
echo "-------"
cat main.py
echo

echo "math.py"
echo "---------"
echo
cat math.py
echo

echo "Running main.py..."
python main.py