V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
crella
V2EX  ›  问与答

Python 的 import 的对象类型问题

  •  
  •   crella · 2020-07-09 11:27:19 +08:00 · 1285 次点击
    这是一个创建于 1599 天前的主题,其中的信息可能已经有所发展或是发生改变。

    学 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()
    
    14 条回复    2020-07-09 23:10:31 +08:00
    linw1995
        1
    linw1995  
       2020-07-09 13:43:54 +08:00
    没有为什么,就是这样设计的。有好想法可以提一下 pep
    xiri
        2
    xiri  
       2020-07-09 13:51:44 +08:00
    如果这里 z 不为字符串,那么应该怎样向 import()传入参数使得 z 能被赋值?

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

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

    把这几个厘清就差不多了
    Trim21
        9
    Trim21  
       2020-07-09 14:47:06 +08:00
    @crella #7 是 os 模块的名字,也是最后被赋值的变量,os 的类型是<class 'module'>
    ipwx
        10
    ipwx  
       2020-07-09 17:47:29 +08:00   ❤️ 1
    @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
        11
    ipwx  
       2020-07-09 18:40:22 +08:00
    诶等等我好像哪里说错了什么。import a.b.c.d 感觉 d 也是模块啊。。
    crella
        12
    crella  
    OP
       2020-07-09 22:31:14 +08:00
    @ipwx 我感觉疑惑的是 import 之后的参数。比如 import os 里的 os,按你的说法,os 的类型是 module,但是在 import 之前执行 os 或者 type(os),都报错:os 这个名称未定义,那么为什么在 import 语句里就能识别出 os 是一个 module 的名称呢?

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

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

    print(a)
    a = 1

    照样也会报名称为定义。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2710 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 06:09 · PVG 14:09 · LAX 22:09 · JFK 01:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.