重新加载在其他模块中导入的子模块
Reload submodule imported in other modules
我有以下问题,我将共享四个不同的 .py 文件以更好地解释我自己。我正在 运行ning 来自 spyder(不是 jupyter)的代码,python 3.4。
我有一个主脚本 "master001.py" 从中执行代码。它看起来像这样:
import sys
before = [str(m) for m in sys.modules]
from importlib import reload
import time
#from child001 import calculation as calc
import child001
from child002 import calculation_two
from child003 import calculation_three
after = [str(m) for m in sys.modules]
print("########################")
print([m for m in after if not m in before])
print("########################\n")
stop = False
while stop == False:
print("\n\n\n\n\n\n\n")
reload_child_one = input("reload child 1 function? Enter Y or N\n")
reload_child_one = reload_child_one.lower()
if reload_child_one == "y":
print("Script will try to reload the calculation 1 / child 1 module.")
time.sleep(1)
reload(child001)
reload_child_two = input("reload child 2 function? Enter Y or N\n")
reload_child_two = reload_child_two.lower()
if reload_child_two == "y":
print("Script will try to reload the calculation 2 / child 2 module.")
time.sleep(1)
#reload(sys.modules[calculation_two.__module__])
#del calculation_two
#from child002 import calculation_two
#__import__("child002", fromlist='calculation_two')
calculation_two = reload(sys.modules["child002"]).calculation_two
print("\n####################################################")
a = input("Enter number that will be saved in variable 'a' or enter Q to quit prorgam\n")
if a.lower() == "q" :
stop = True
print("\nFunction complted. Script will quit.")
print("####################################################\n")
time.sleep(2)
else:
try:
a = int(a)
print("Master - Launching Child function 'calculation'")
b = child001.calculation(a)
print("\nMaster - Inside Master file. Result = b = {}".format(b))
print("####################################################\n")
print("Master - Launching Child 2 function 'calculation_two' on input variable")
c = calculation_two(a)
print("\nMaster - Inside Master file. Result = c = {}".format(c))
print("####################################################\n")
print("Master - Launching child 3")
calculation_three()
time.sleep(2)
except:
print("input value was not a valid number. Please, try again.\n")
print("####################################################\n")
time.sleep(2)
master001.py调用child001.py进行简单计算:
print("wassupp from child 1 !!!")
def calculation(a):
print("\n----------------------------------------")
print("Child 1 - function 'calculation' started.")
print("Child 1 - Operation that will be executed is: input variable + 20")
result = a + 20
print("Child 1 - Returning result = {}".format(result))
print("----------------------------------------\n")
return result
然后,master001.py 调用 child002.py,其中执行另一个简单的计算:
print("wassupp from child 2 !!!")
def calculation_two(a):
print("\n----------------------------------------")
print("Child 2 - function 'calculation_two' started.")
print("Child 2 - Operation that will be executed is: input variable + 200")
result = a + 200
print("Child 2 - Returning result = {}".format(result))
print("----------------------------------------\n")
return result
到目前为止一切顺利。最后,我有child003.py。在这个模块中,我执行了一个实际从 child002.py
导入的计算
from child002 import calculation_two
print("wassupp from child 3 !!!")
def calculation_three():
print("\n----------------------------------------")
print("Child 3 function - Calculation will use the one in child 2 applied to value '3'.!\n")
result = calculation_two(3)
print("Child 3 - result = {}".format(result))
print("----------------------------------------\n")
return
正如您从 运行ning master001.py 中看到的那样,当我使用
重新加载 calculation_two 时
calculation_two = reload(sys.modules["child002"]).calculation_two
适用于 child002.py
中的 calculation_two
运行,但它不会重新加载 child003.py
调用的 calculation_two
。
更具体地说,如果您 运行 master001.py
并且在手动输入任何内容之前更改了 calculation_two
的内容,那么当您被询问时
reload child 1 function? Enter Y or N
你输入 N,当你被问到时
reload child 2 function? Enter Y or N
您输入 Y,您将看到 child003.py
返回的值未反映新的更新代码。
我读过 How do I unload (reload) a Python module? and How to reload python module imported using `from module import *` 它们非常有用,但我找不到解决这个特定问题的方法。
您的问题在于如何从 child002
:
导入函数
from child002 import calculation_two
这将创建对 child003
中函数对象的引用,并且该引用未被替换。 Python 名称就像字符串上的标签,绑定到对象上。您可以将多个标签绑定到一个对象,如果您想 将那个对象替换 到另一个对象,那么您必须确保重新绑定所有这些标签。
你从这个开始:
sys.modules['child002']
-> module object created from child002.py
-> module.__dict__ (the module globals)
-> module.__dict__['calculation_two']
|
|
+--> function object named calculation_two
|
|
-> module.__dict__['calculation_two']
-> module.__dict__ (the module globals)
-> module object for child003.py
sys.modules['child003']
然后当您重新加载 child002
模块时,Python 会用新对象替换所有现有的全局变量,所以现在您有:
sys.modules['child002']
-> module object created from child002.py
-> module.__dict__ (the module globals)
-> module.__dict__['calculation_two']
|
|
+--> *new* function object named calculation_two
+--> *old* function object named calculation_two
|
|
-> module.__dict__['calculation_two']
-> module.__dict__ (the module globals)
-> module object for child003.py
sys.modules['child003']
因为child003
模块对象中的calculation_two
引用是一个独立的标签
您要么必须手动替换该标签:
calculation_two = reload(sys.modules["child002"]).calculation_two
child003.calculation_two = calculation_two
或者您可以不直接引用 calculation_two
,而是仅引用 child002
模块:
import child002
# ...
def calculation_three():
# ...
result = child002.calculation_two(3)
此时你有以下关系:
sys.modules['child002']
-> module object created from child002.py
^ -> module.__dict__ (the module globals)
| -> module.__dict__['calculation_two']
| |
| |
| +--> function object named calculation_two
|
|
+------------+
|
|
-> module.__dict__['child002']
-> module.__dict__ (the module globals)
-> module object for child003.py
sys.modules['child003']
我可以推荐阅读 Ned Batchelder's explanation of Python names and values 以从另一个角度看待这个问题。
我有以下问题,我将共享四个不同的 .py 文件以更好地解释我自己。我正在 运行ning 来自 spyder(不是 jupyter)的代码,python 3.4。 我有一个主脚本 "master001.py" 从中执行代码。它看起来像这样:
import sys
before = [str(m) for m in sys.modules]
from importlib import reload
import time
#from child001 import calculation as calc
import child001
from child002 import calculation_two
from child003 import calculation_three
after = [str(m) for m in sys.modules]
print("########################")
print([m for m in after if not m in before])
print("########################\n")
stop = False
while stop == False:
print("\n\n\n\n\n\n\n")
reload_child_one = input("reload child 1 function? Enter Y or N\n")
reload_child_one = reload_child_one.lower()
if reload_child_one == "y":
print("Script will try to reload the calculation 1 / child 1 module.")
time.sleep(1)
reload(child001)
reload_child_two = input("reload child 2 function? Enter Y or N\n")
reload_child_two = reload_child_two.lower()
if reload_child_two == "y":
print("Script will try to reload the calculation 2 / child 2 module.")
time.sleep(1)
#reload(sys.modules[calculation_two.__module__])
#del calculation_two
#from child002 import calculation_two
#__import__("child002", fromlist='calculation_two')
calculation_two = reload(sys.modules["child002"]).calculation_two
print("\n####################################################")
a = input("Enter number that will be saved in variable 'a' or enter Q to quit prorgam\n")
if a.lower() == "q" :
stop = True
print("\nFunction complted. Script will quit.")
print("####################################################\n")
time.sleep(2)
else:
try:
a = int(a)
print("Master - Launching Child function 'calculation'")
b = child001.calculation(a)
print("\nMaster - Inside Master file. Result = b = {}".format(b))
print("####################################################\n")
print("Master - Launching Child 2 function 'calculation_two' on input variable")
c = calculation_two(a)
print("\nMaster - Inside Master file. Result = c = {}".format(c))
print("####################################################\n")
print("Master - Launching child 3")
calculation_three()
time.sleep(2)
except:
print("input value was not a valid number. Please, try again.\n")
print("####################################################\n")
time.sleep(2)
master001.py调用child001.py进行简单计算:
print("wassupp from child 1 !!!")
def calculation(a):
print("\n----------------------------------------")
print("Child 1 - function 'calculation' started.")
print("Child 1 - Operation that will be executed is: input variable + 20")
result = a + 20
print("Child 1 - Returning result = {}".format(result))
print("----------------------------------------\n")
return result
然后,master001.py 调用 child002.py,其中执行另一个简单的计算:
print("wassupp from child 2 !!!")
def calculation_two(a):
print("\n----------------------------------------")
print("Child 2 - function 'calculation_two' started.")
print("Child 2 - Operation that will be executed is: input variable + 200")
result = a + 200
print("Child 2 - Returning result = {}".format(result))
print("----------------------------------------\n")
return result
到目前为止一切顺利。最后,我有child003.py。在这个模块中,我执行了一个实际从 child002.py
导入的计算from child002 import calculation_two
print("wassupp from child 3 !!!")
def calculation_three():
print("\n----------------------------------------")
print("Child 3 function - Calculation will use the one in child 2 applied to value '3'.!\n")
result = calculation_two(3)
print("Child 3 - result = {}".format(result))
print("----------------------------------------\n")
return
正如您从 运行ning master001.py 中看到的那样,当我使用
重新加载 calculation_two 时calculation_two = reload(sys.modules["child002"]).calculation_two
适用于 child002.py
中的 calculation_two
运行,但它不会重新加载 child003.py
调用的 calculation_two
。
更具体地说,如果您 运行 master001.py
并且在手动输入任何内容之前更改了 calculation_two
的内容,那么当您被询问时
reload child 1 function? Enter Y or N
你输入 N,当你被问到时
reload child 2 function? Enter Y or N
您输入 Y,您将看到 child003.py
返回的值未反映新的更新代码。
我读过 How do I unload (reload) a Python module? and How to reload python module imported using `from module import *` 它们非常有用,但我找不到解决这个特定问题的方法。
您的问题在于如何从 child002
:
from child002 import calculation_two
这将创建对 child003
中函数对象的引用,并且该引用未被替换。 Python 名称就像字符串上的标签,绑定到对象上。您可以将多个标签绑定到一个对象,如果您想 将那个对象替换 到另一个对象,那么您必须确保重新绑定所有这些标签。
你从这个开始:
sys.modules['child002']
-> module object created from child002.py
-> module.__dict__ (the module globals)
-> module.__dict__['calculation_two']
|
|
+--> function object named calculation_two
|
|
-> module.__dict__['calculation_two']
-> module.__dict__ (the module globals)
-> module object for child003.py
sys.modules['child003']
然后当您重新加载 child002
模块时,Python 会用新对象替换所有现有的全局变量,所以现在您有:
sys.modules['child002']
-> module object created from child002.py
-> module.__dict__ (the module globals)
-> module.__dict__['calculation_two']
|
|
+--> *new* function object named calculation_two
+--> *old* function object named calculation_two
|
|
-> module.__dict__['calculation_two']
-> module.__dict__ (the module globals)
-> module object for child003.py
sys.modules['child003']
因为child003
模块对象中的calculation_two
引用是一个独立的标签
您要么必须手动替换该标签:
calculation_two = reload(sys.modules["child002"]).calculation_two
child003.calculation_two = calculation_two
或者您可以不直接引用 calculation_two
,而是仅引用 child002
模块:
import child002
# ...
def calculation_three():
# ...
result = child002.calculation_two(3)
此时你有以下关系:
sys.modules['child002']
-> module object created from child002.py
^ -> module.__dict__ (the module globals)
| -> module.__dict__['calculation_two']
| |
| |
| +--> function object named calculation_two
|
|
+------------+
|
|
-> module.__dict__['child002']
-> module.__dict__ (the module globals)
-> module object for child003.py
sys.modules['child003']
我可以推荐阅读 Ned Batchelder's explanation of Python names and values 以从另一个角度看待这个问题。