我具有以下文件结构:
A:
| _ a.py
| _ b.py
B:
| _ a.py
| _ b.py
我想动态执行A / b.py或B / b.py。
我正在使用以下代码:
from importlib import import_module
path = '/home/username/test/' + module + '/'
if path not in sys.path:
sys.path.append(path)
script = import_module('b', 'Script')
myClass = getattr(script, 'Script')
run = myClass()
这样做,如果我先运行B / b.py,然后运行A / b.py,它将执行B / b.py而不是A / b.py。
要运行的第一个脚本将在下一轮执行。
我需要帮助以确保仅运行我想要的目录中的文件。
答案 0 :(得分:0)
我正在对您要在此处完成的工作进行一些假设。即使这不是您想要的,它仍然可以向您正确的方向:您有两个不同的子目录,分别是 A 和 B 。这些脚本包含名称相同的脚本 a.py 和 b.py 。根据某些条件,您的脚本应调用 A / a.py 或 A / a.py ,然后那么可能是 B / b.py 或 B / b.py 。
我将 A 和 B 设置为实际的python模块,即在两个文件夹中创建一个 __ init __。py 文件。然后有一个主脚本,以某种方式确定要使用哪个模块。
# root_folder/master.py
import sys
import A
import B
master_script_name = sys.argv[0]
print("I'm the master script : " + str(master_script_name))
def choose_module_A_or_B(arg):
if arg == "A":
print(" You chose module A !")
return A
return B
module = choose_module_A_or_B("A")
module.b.print_locations()
然后
# root_folder/A/__init__.py
from A import b
和
# root_folder/A/b.py
import os
import sys
# how to obtain paths and script name:
folder = os.path.dirname(os.path.realpath(__file__))
script = __file__
parent = os.path.abspath(os.path.join(folder, os.pardir))
def print_locations():
print(" --> script : " + str(script))
print(" --> folder : " + str(folder))
print(" --> parent : " + str(parent))
Similally ..
# root_folder/B/__init__.py
from B import b
和
# root_folder/B/b.py
import os
import sys
# how to obtain paths and script name:
folder = os.path.dirname(os.path.realpath(__file__))
script = __file__
parent = os.path.abspath(os.path.join(folder, os.pardir))
def print_locations():
print(" --> script : " + str(script))
print(" --> folder : " + str(folder))
print(" --> parent : " + str(parent))
输出:
$ python master.py
I'm the master script : master.py
You chose module A !
--> script : A\b.py
--> folder : C:\dev\ScriptTesting\py\script_by_name\A
--> parent : C:\dev\ScriptTesting\py\script_by_name
答案 1 :(得分:0)
我已经阅读了您的其他类似question,并提出了没有任何预导入的解决方案。 (恕我直言)这是非常不符合Python的语言,因此绝对可以认为是肮脏的“ hack”。我强烈建议您考虑我的其他答案,并妥善处理进口问题。
发生您的问题是因为您要破坏名称空间,而所有名称空间都很宝贵。当您使用具有相同签名的函数/方法对名称空间进行污染时,Python解释器绝对无法区分它们:它将解析为首次导入的名称。
但是,如上所述,有一种解决方法:(当前)无法卸载 python模块,但是您可以使用reload
imp
模块。本质上,它使您可以清理(重新定义)名称空间。您可以在我的repl.it
# root_folder/main.py
import sys
import imp
from importlib import import_module
def import_script(mod_dir, script):
sys.path.append(mod_dir)
mod = imp.reload(import_module(script, 'Script'))
sys.path.remove(mod_dir)
return mod
# input:
mod_dir = "A"
script = "b"
# import module/script.py
active_mod = import_script(mod_dir, script)
# use module/script.py
mod_name = active_mod.get_mod_name()
print(mod_name) # Prints "A : b.y"
# New input: different module/script.py
mod_dir = "C"
script = "b"
# import module/script.py
active_mod = import_script(mod_dir, script)
# use module/script.py
mod_name = active_mod.get_mod_name()
print(mod_name) # Prints "C : b.y"
当模块如下所示时,
# root_folder/A/b.py
def get_mod_name():
return "A : b.py"
请注意,每次导入都会加倍,因为每次导入模块(名称可能重复)时,都必须重新加载模块以清理名称空间。仅del
模块是不够的。