当我说,
>>>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
类型的对象。
我的问题:
我的理解是否正确?
或
radius
和sqrt
和square
对象是否在__main__
模块的全局框架和参考变量(radius
sqrt
{{1}之外创建坐在square
模块的全局框架内指向这些对象?
在CS61A 2012秋季课程中,老师说,这就是它,它看起来像隐藏了许多python程序内存模型的细节。
答案 0 :(得分:2)
询问创建对象的位置与引用所在的位置有点没有实际意义。正如200 OK在评论中指出的那样,所有对象名称都是引用 - 没有比其他名称更规范或本地的名称。对象只是存在(在私有堆上,虽然这对于所有意图和目的都无关紧要),并且名称指向它们。
那就是说,你的问题中有一个不太恰当的细微差别。当您从模块导入某些内容时 - 无论是整个模块本身,还是仅仅是一个函数 - 对该模块的引用都存储在sys.modules
dict中。这确保了当代码的另一部分从该模块导入时,它不会被重新导入;使用现有的导入版本。
答案 1 :(得分:0)
在内部,
radius
模块的全局框架中创建了一个名为__main__
的新对象,该对象属于int
类。
您正在混淆对象的引用创建和绑定(赋值)。声明radius = 2
导致......
2
,它可能会也可能不会创建一个对象(在CPython中它不会因为小整数被缓存),那么radius
绑定到评估生成的对象(值)。同样,在import
案例中,import
可能会也可能不会创建对象。如果之前导入了math
,则已创建其对象。您只需将新名称sqrt
分配给通过导入math
模块创建的对象。询问对象是否驻留在模块中是没有意义的,因为对象不存在于模块中。它们可能由模块引用或由导入创建,但之后,它们只在一个大而扁平的堆空间中。它是对它们的引用,形成一个结构化的命名空间。
def
的特殊之处在于它会导致对函数对象进行评估和绑定。