我有一个糖化酶.pypyspark目录中的文件。在REPL中,我尝试重新加载它:
>>> reload(pyspark.hbase)
<module 'pyspark.hbase' from '/shared/hwspark2/python/pyspark/hbase.py'>
>>> from pyspark.hbase import *
>>> # run the code .. latest changes not apparent..
没有错误。。但是,类的定义没有更新,新的print语句没有出现就证明了这一点。在
在退出解释器并重新加载模块后,可以看到更新。然而,即使在调用reload之后,对该模块的任何进一步更改都不可见。在
这个问题还不完全清楚,但我认为你误解了^{} 的作用。在
它重新导入模块,包括其中定义的所有新类对象,并更改
sys.modules[name]
以引用新的模块对象,还将名称复制到全局变量中。在但这就是一切。它不会自动找到对旧模块的所有引用,更不用说旧模块中定义的任何内容,等等,并将它们全部修复为引用替换版本。(怎么可能?新模块中甚至可能没有替代版本。因此,如果您的值是由旧代码计算的,并且计算方式不同,那么会怎样;它必须重新运行导入模块后所做的所有操作。)
文档(上面的链接)用不同的术语解释了它,但是让我们把它具体化,这样我可以更直接地解释它。在
创建此文件:
现在:
^{pr2}$现在编辑它:
当您通过调用},然后调用其构造函数和初始值设定项,给您一个对象,该对象的
mod.Spam()
来创建spam
,它在全局中查找'mod'
,然后在结果模块中查找{__class__
是对该mod.Spam
类的引用。在当您调用},否则,在}。我们知道,这就是
spam.eggs()
时,Python在全局字典中查找'spam'
,在spam
对象的字典中查找{spam.__class__
对象的字典中查找{mod.Spam
对象,它有一个eggs
方法,因此被调用。在现在,在我们}。因此,当您第二次调用}中查找{},找到与之前相同的类,并调用与之前相同的函数。在
reload(mod)
之后,有一个名为'mod'
的新对象,它有一个名为'Spam'
的新类作为成员。但是旧的mod
和mod.Spam
对象,以及您的spam
-仍然存在。而现有的spam
在其__class__
中仍然引用了旧的{spam.eggs()
时,与之前完全相同的情况发生。Python将'spam'
作为全局查找,首先在spam
中查找'eggs'
,然后在{当我们再次调用}。然后在该模块中查找
mod.Spam()
来构造morespam
时,现在它在全局中查找'mod'
,并找到新的{'Spam'
,并找到新类。因此,我们有一个实例,它的__class__
是新的mod.Spam
。当我们调用它的eggs
方法时,会发生与上面相同的情况,但现在调用的是新函数。在使用}会使事情变得更难理解,但基本思想是相同的。
from mod import *
而不是{from mod import *
不会将mod
放入全局变量,而是将其所有非私有全局变量(在mod.__all__
中列出的任何内容,或者,如果不存在这样的内容,mod
中不以一个下划线开头的任何内容)复制到全局变量。因此,reload
创建一个新的模块对象,第二个from mod import *
将新模块的所有非私有全局变量复制到全局变量中,替换旧的全局变量。但是您的spam
实例仍然是旧的Spam
的实例,而不是新实例。在脑海中浮现出三种可能性(一种是@abarner的):
pyspark.hbase
有一个__all__
,而您尝试使用的类不在其中pyspark.hbase
没有__all__
,但类名/函数等以_
开头。在__all__
用作模块定义其官方API的一种方式。它还用于提供在发出from ... import *
时要导入的名称列表。如果未定义__all__
,那么在该模块上使用from ... import *
时,将加载该模块中任何不以_
开头的名称。在无论是否定义了
__all__
,您始终可以通过直接请求来显式加载模块中定义的任何名称:{12>将加载到你的命名空间中。在
相关问题 更多 >
编程相关推荐