Python 的 import 的对象类型问题

2020-07-09 11:27:19 +08:00
 crella

学 python,熟悉 from x import y as z 的形式。那么这里的 x 和 y 是什么类型的对象?为什么一开始不设置成字符串的形式,比如

from './x' import 'y' as z # 如果这里 z 不为字符串,那么应该怎样向 import()传入参数使得 z 能被赋值?
# 或者另一种方式
from 'x' import 'y' # 在 python 库目录里寻找以 x 为名称的包
y.Function()
1286 次点击
所在节点    问与答
14 条回复
linw1995
2020-07-09 13:43:54 +08:00
没有为什么,就是这样设计的。有好想法可以提一下 pep
xiri
2020-07-09 13:51:44 +08:00
如果这里 z 不为字符串,那么应该怎样向 import()传入参数使得 z 能被赋值?

这个问题,你不知道 python 可以像下面这样搞吗?
def x():
print("hello")
y=x
y()
xiri
2020-07-09 13:53:15 +08:00
@xiri v 站回复会把缩进吃掉,,,上面的回复中的代码前两行定义了一个函数 x,然后 y=x,最后加上括号,用 y()来调用
ipwx
2020-07-09 13:53:20 +08:00
??? 没看懂你的问题是什么。

学一样语言不要把上一个语言认为天经地义的东西代入进来,因为可能在这个语言里面根本不存在对应的概念。
lln133208
2020-07-09 13:55:56 +08:00
'x'这不是代表字符串吗?
from ‘x’ 这种写法也太反直觉了吧
ipwx
2020-07-09 13:56:49 +08:00
@lln133208 估计是 JS 转过来的,那个世界的 import 是文件路径。
crella
2020-07-09 14:23:13 +08:00
@ipwx 比如 import os 这句,os 是指变量名还是符号量还是啥?这个 os 是在 python 启动时被定义在某个命名空间里的吗?
westoy
2020-07-09 14:31:58 +08:00
PYTHONPATH
sys.modules
__import__ / importlib
types.ModuleType

把这几个厘清就差不多了
Trim21
2020-07-09 14:47:06 +08:00
@crella #7 是 os 模块的名字,也是最后被赋值的变量,os 的类型是<class 'module'>
ipwx
2020-07-09 17:47:29 +08:00
@crella

1. 最好不要每个东西都拆开来理解。import a.b.c.d / from a.b.c.d import x 这都是某种语法约定,拆开来理解没有意义的。(如果硬要追寻答案:import a.b.c.d 的话,a/b/c 至少每个肯定是 module 。d 可能是 module 也可能是 function, object 之类的。但是这是执行完这条语句之后的结果,在这条语句中没有特定意义)

2. python 遇到 import 会根据 sys.path 里面的路径依次查找模块,找到就进行导入。你可以 import sys 然后看看 sys.path 。另外 sys.path 可以受到 PYTHONPATH 环境变量的影响。

3. 导入过的模块都能在 sys.modules 中找到。如果一个模块已经被导入了一次,那么第二次 import 它不会产生第二次导入,只是把这个 sys.modules 里面的这个模块对象给你拿出来。这也是为啥我说拆开看 import 里面每个符号是啥意思完全没有意义。

4. 你完全可以通过 __import__ 和 getattr 自己写一个根据字符串导入某个对象 /模块的函数。

5. 模块的类型是 types.ModuleType
ipwx
2020-07-09 18:40:22 +08:00
诶等等我好像哪里说错了什么。import a.b.c.d 感觉 d 也是模块啊。。
crella
2020-07-09 22:31:14 +08:00
@ipwx 我感觉疑惑的是 import 之后的参数。比如 import os 里的 os,按你的说法,os 的类型是 module,但是在 import 之前执行 os 或者 type(os),都报错:os 这个名称未定义,那么为什么在 import 语句里就能识别出 os 是一个 module 的名称呢?

在这个问题上我是有点钻牛角尖,这个超出了我对面向对象编程知识的认知,所以才好奇问一下。反正不影响实际使用。
Trim21
2020-07-09 22:52:52 +08:00
@crella import 不是一个函数,os 也不是穿给 import 的一个参数…
就好象 let a=1 里面的 a 在这一行之前也是不存在的啊
ipwx
2020-07-09 23:10:31 +08:00
@crella 楼上正解。import 根本就不是函数,是个语句。就和 int a = 1; 不也能创建一个 a 变量一样么?

另外说一句,看起来你是从 C++ 或者 Java 那里转过来的? Python 是脚本语言,所以在一行执行之前,这行会产生的标识符就是不存在。比如

print(a)
a = 1

照样也会报名称为定义。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/688488

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX