代码之家  ›  专栏  ›  技术社区  ›  l7ll7

python如何处理来自“其他地方”的对象

  •  3
  • l7ll7  · 技术社区  · 6 年前

    这可能是一个愚蠢的问题,但我不了解如何使用我们没有定义或导入的对象。

    考虑下面的示例,使用python的 datetime 模块:

    from datetime import date
    
    date1 = date(2019,1,1)
    date2 = date(2019,1,5)
    
    type(date2-date1) #<class 'datetime.timedelta'>
    type(date2)       #<class 'datetime.date'>
    

    然后 date2-date1 timedelta 类,即使我们尚未导入此。

    (我也可以编出其他的例子,在那里我们获取对象,即使我们没有定义它们。)

    怎么会这样?

    我是否应该考虑这些新的对象,这些新对象只是作为内存中的一部分弹出,由其他函数返回,即使我们没有定义它们,它们本身也包含足够的信息,以便python解释器可以有意义地应用 type() 还有其他的功能?

    2 回复  |  直到 6 年前
        1
  •  5
  •   Martijn Pieters    6 年前

    你错误地认为 import 限制加载到内存中的内容。 进口 限制什么 名称绑定在模块全局中 .

    整个模块仍然被加载,该模块的依赖项也是如此。只是因为 命名空间 不将引用绑定到 datetime.timedelta 对象并不意味着它对 datetime 模块。

    import statement documentation :

    这个 from 表单使用稍微复杂一点的过程:

    1. 查找中指定的模块 条款,必要时加载并初始化;
    2. 对于中指定的每个标识符 进口 条款:
      1. 检查导入的模块是否具有该名称的属性
      2. 如果没有,请尝试导入具有该名称的子模块,然后再次检查导入的模块是否具有该属性。
      3. 如果找不到属性, ImportError 提高了。
      4. 否则,对该值的引用将存储在本地命名空间中,如果存在,则使用as子句中的名称,否则使用属性名称。

    因此加载和初始化模块是一个单独的步骤, 执行一次 每个模块。第二步绑定命名空间中的名称。

    from datetime import date 确保 日期时间 模块已加载,然后查找 datetime.date 并添加 date = datetime.date 你的 命名空间。

    如果要查看加载了哪些模块,请检查 sys.modules mapping . 这就是 import statement machinery checks 查看给定模块是否已加载。

        2
  •  1
  •   Urbano    6 年前
    from datetime import date
    

    日期正在某处导入TimeDelta,因为它可能是一个依赖项,即使您没有看到它。