在Python中,一旦我使用import X
在解释器会话中导入模块X,并且模块在外部更改,我可以使用reload(X)
重新加载模块。然后,我的翻译会话就可以进行更改。
我想知道当我使用from X import Y
从模块X导入组件Y时是否也可以这样做。
语句reload Y
不起作用,因为Y不是模块本身,而只是模块内部的一个组件(在本例中是一个类)。
是否可以在不离开解释器会话(或导入整个模块)的情况下重新加载模块的各个组件?
修改
为了澄清,问题是从模块X 导入类或函数Y 并重新加载更改,而不是从包X中重新加载模块Y. / p>
答案 0 :(得分:77)
从我的测试中。标记的答案表明一个简单的reload(X)
,但不起作用。
据我所知,正确的答案是:
# python3.x would require
# from importlib import reload
import X
reload( X )
from X import Y
我的测试如下(Python 2.6.5 + bpython 0.9.5.2)
X.py:
def Y():
print "Test 1"
bpython:
>>> from X import Y
>>> print Y()
Test 1
>>> # Edit X.py to say "Test 2"
>>> print Y()
Test 1
>>> reload( X ) # doesn't work because X not imported yet
Traceback (most recent call last):
File "<input>", line 1, in <module>
NameError: name 'X' is not defined
>>> import X
>>> print Y()
Test 1
>>> print X.Y()
Test 1
>>> reload( X ) # No effect on previous "from" statements
>>> print Y()
Test 1
>>> print X.Y() # first one that indicates refresh
Test 2
>>> from X import Y
>>> print Y()
Test 2
>>> # Finally get what we were after
答案 1 :(得分:47)
如果Y是一个模块(并且X是一个包)reload(Y)
会没问题 - 否则,你会看到为什么好的Python风格指南(比如我的雇主)对从不导入任何除了一个模块(这是众多重要原因中的一个 - 然而人们仍然会直接导入函数和类,无论我多么解释它不一个好主意; - )。
答案 2 :(得分:7)
首先,如果你可以避免,你根本不应该使用重装。但是我们假设你有理由(即在IDLE中调试)。
重新加载库不会将名称返回到模块的命名空间中。为此,只需重新分配变量:
f = open('zoo.py', 'w')
f.write("snakes = ['viper','anaconda']\n")
f.close()
from zoo import snakes
print snakes
f = open('zoo.py', 'w')
f.write("snakes = ['black-adder','boa constrictor']\n")
f.close()
import zoo
reload(zoo)
snakes = zoo.snakes # the variable 'snakes' is now reloaded
print snakes
你可以通过其他几种方式做到这一点。您可以通过搜索本地命名空间来自动化该过程,并重新分配来自相关模块的任何内容,但我认为我们已经足够邪恶了。
答案 3 :(得分:7)
from modulename import func
import sys
reload(sys.modules['modulename'])
from modulename import func
答案 4 :(得分:4)
如果你想这样做:
GROUP BY
请改为:
SELECT sum(mean(value) GROUP BY "instance") FROM "queues_value" WHERE "host" =~ /$host/ AND "type" = 'rabbitmq_messages' AND $timeFilter GROUP BY time($interval), "host"
现在你可以按照你计划的方式使用myobject(没有令人厌烦的不可读的mymodule引用)。
如果您正在以交互方式工作并想从mymodule重新加载myobject,那么您现在可以使用:
SELECT sum(value) FROM (SELECT mean(value) FROM "queues_value" WHERE "host" =~ /$host/ AND "type" = 'rabbitmq_messages' AND $timeFilter GROUP BY time($interval), "host", "instance") GROUP BY time($interval), "host"
答案 5 :(得分:2)
假设您使用了from X import Y
,您有两种选择:
reload(sys.modules['X'])
reload(sys.modules[__name__]) # or explicitly name your module
或
Y=reload(sys.modules['X']).Y
一些注意事项:
一个。如果导入范围不是模块范围的(例如,在函数中导入) - 则必须使用第二个版本。
B中。如果Y从另一个模块(Z)导入X - 您必须重新加载Z,而不是重新加载X而不是重新加载模块,甚至重新加载所有模块(例如:使用[ reload(mod) for mod in sys.modules.values() if type(mod) == type(sys) ]
)可能会在重新加载Z之前重新加载X - 而不是刷新Y的值。
答案 6 :(得分:1)
reload()
模块X
,reload()
模块从Y
导入X
。请注意,重新加载不会更改已绑定在其他命名空间中的已创建对象(即使您遵循Alex的样式指南)。
答案 7 :(得分:0)
为了跟进AlexMartelli's和Catskul's的答案,有一些非常简单但令人讨厌的案例似乎让reload
感到困惑,至少在Python 2中是这样。
假设我有以下源树:
- foo
- __init__.py
- bar.py
具有以下内容:
init.py:
from bar import Bar, Quux
bar.py:
print "Loading bar"
class Bar(object):
@property
def x(self):
return 42
class Quux(Bar):
object_count = 0
def __init__(self):
self.count = self.object_count
self.__class__.object_count += 1
@property
def x(self):
return super(Quux,self).x + 1
def __repr__(self):
return 'Quux[%d, x=%d]' % (self.count, self.x)
这可以正常使用reload
:
>>> from foo import Quux
Loading bar
>>> Quux()
Quux[0, x=43]
>>> Quux()
Quux[1, x=43]
>>> Quux()
Quux[2, x=43]
但是尝试重新加载它要么没有效果要么腐败:
>>> import foo
Loading bar
>>> from foo import Quux
>>> Quux()
Quux[0, x=43]
>>> Quux()
Quux[1, x=43]
>>> reload(foo)
<module 'foo' from 'foo\__init__.pyc'>
>>> Quux()
Quux[2, x=43]
>>> from foo import Quux
>>> Quux()
Quux[3, x=43]
>>> reload(foo.bar)
Loading bar
<module 'foo.bar' from 'foo\bar.pyc'>
>>> Quux()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "foo\bar.py", line 17, in __repr__
return 'Quux[%d, x=%d]' % (self.count, self.x)
File "foo\bar.py", line 15, in x
return super(Quux,self).x + 1
TypeError: super(type, obj): obj must be an instance or subtype of type
>>> Quux().count
5
>>> Quux().count
6
>>> Quux = foo.bar.Quux
>>> Quux()
Quux[0, x=43]
>>> foo.Quux()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "foo\bar.py", line 17, in __repr__
return 'Quux[%d, x=%d]' % (self.count, self.x)
File "foo\bar.py", line 15, in x
return super(Quux,self).x + 1
TypeError: super(type, obj): obj must be an instance or subtype of type
>>> foo.Quux().count
8
我确保重新加载bar
子模块的唯一方法是reload(foo.bar)
;我访问重新加载的Quux
类的唯一方法是进入并从重新加载的子模块中获取它;但foo
模块本身仍保留原始Quux
类对象,大概是因为它使用from bar import Bar, Quux
(而不是import bar
后跟Quux = bar.Quux
);此外,Quux
类与自身不同步,这很奇怪。
答案 8 :(得分:0)
如果您在Jupyter环境中工作,并且已经拥有from module import function
可以使用魔术功能autoreload
,
%load_ext autoreload
%autoreload
from module import function
在here中给出了IPython中autoreload
的介绍。