查询Python中的命名

时间:2014-07-03 12:39:56

标签: python

当我说,

>>>radius = 2

在内部,radius模块的全局框架中创建了一个名为__main__的新对象,该对象属于类int。引用变量也是由名称radius创建的,它指向该对象。

当我说,

>>>from math import sqrt

在内部,sqrt模块的全局框架中创建了一个名为__main__的新对象,该对象属于类function。引用变量也是由名称sqrt创建的,它指向function类型的对象。

当我说,

>>>def square(x):
         return mul(x,x)

在内部,square模块的全局框架中创建了一个名为__main__的新对象,该对象属于类function。引用变量也是由名称square创建的,它指向function类型的对象。

我的问题:

我的理解是否正确?

radiussqrtsquare对象是否在__main__模块的全局框架和参考变量(radius sqrt {{1}之外创建坐在square模块的全局框架内指向这些对象?

在CS61A 2012秋季课程中,老师说,这就是它,它看起来像隐藏了许多python程序内存模型的细节。

program environment in memory

2 个答案:

答案 0 :(得分:2)

询问创建对象的位置与引用所在的位置有点没有实际意义。正如200 OK在评论中指出的那样,所有对象名称都是引用 - 没有比其他名称更规范或本地的名称。对象只是存在(在私有堆上,虽然这对于所有意图和目的都无关紧要),并且名称指向它们。

那就是说,你的问题中有一个不太恰当的细微差别。当您从模块导入某些内容时 - 无论是整个模块本身,还是仅仅是一个函数 - 对该模块的引用都存储在sys.modules dict中。这确保了当代码的另一部分从该模块导入时,它不会被重新导入;使用现有的导入版本。

答案 1 :(得分:0)

  

在内部,radius模块的全局框架中创建了一个名为__main__的新对象,该对象属于int类。

您正在混淆对象的引用创建和绑定(赋值)。声明radius = 2导致......

  • 评估表达式2,它可能会也可能不会创建一个对象(在CPython中它不会因为小整数被缓存),那么
  • 将名称radius绑定到评估生成的对象(值)。

同样,在import案例中,import可能会也可能不会创建对象。如果之前导入了math,则已创建其对象。您只需将新名称sqrt分配给通过导入math模块创建的对象。询问对象是否驻留在模块中是没有意义的,因为对象不存在于模块中。它们可能由模块引用或由导入创建,但之后,它们只在一个大而扁平的堆空间中。它是对它们的引用,形成一个结构化的命名空间。

def的特殊之处在于它会导致对函数对象进行评估和绑定。