Python 如何从模块中只加载一个类?
我有密码:Python 如何从模块中只加载一个类?,python,python-2.x,python-import,Python,Python 2.x,Python Import,我有密码: mod_file = 'mymod.py' mod_path = os.path.join('.', mod_file) mod_py = 'mymod' mod = imp.load_source(mod_py, mod_path) if hasattr(mod, 'MyClass'): instance = py_mod.MyClass() mymod.py: class MyClass(): def __init__(self): print
mod_file = 'mymod.py'
mod_path = os.path.join('.', mod_file)
mod_py = 'mymod'
mod = imp.load_source(mod_py, mod_path)
if hasattr(mod, 'MyClass'):
instance = py_mod.MyClass()
mymod.py:
class MyClass():
def __init__(self):
print 'Hello'
[...]
print 'something'
a = MyClass()
但是“imp.load_source”会执行此文件中的所有指令。我只想得到类MyClass-和其他东西跳过。怎么做
编辑:
我不能干涉“mymod.py”文件,我不知道该文件将如何命名,这就是示例
我知道文件中的类将是“MyClass”。其他事情是不可取的
class MyClass():
def __init__(self):
print 'Hello'
[...]
if __name__ == '__main__':
print 'something'
a = MyClass()
if _; name _;
块中的所有语句仅在直接执行该模块时执行,而不是在导入模块时执行
只有在直接执行模块而不是导入模块时,
if\uuuuu name\uuuuu
块中的所有语句才会执行。您可以像这样将结束行包装在mymod.py
中:
if __name__ == "__main__":
print 'something'
a = MyClass()
结果是,这些行仅在mymod.py
作为脚本执行时执行,而不是作为模块导入。请参阅Python文档中的
但是请注意,如果您在mymod.py
中定义了其他类,它们仍将由imp.load\u source
导入
编辑:由于无法修改mymod.py
,解决方案变得更加复杂。您可以使用模块解析代码:
import ast
with open("mymod.py", "r") as fd:
module_ast = ast.parse("".join(fd.readlines()))
然后,您将遍历ast(
module_ast
),并隔离MyClass
树节点。这个链接提供了一个修改python代码内联的方法,并展示了如何。您可以使用这些链接中的技术组合来隔离与MyClass
相关的ast
节点,并删除其余节点。但这最终会对mymod.py
实际包含的内容做出一些假设。您可以将结束行包装在mymod.py
中,如下所示:
if __name__ == "__main__":
print 'something'
a = MyClass()
结果是,这些行仅在mymod.py
作为脚本执行时执行,而不是作为模块导入。请参阅Python文档中的
但是请注意,如果您在mymod.py
中定义了其他类,它们仍将由imp.load\u source
导入
编辑:由于无法修改mymod.py
,解决方案变得更加复杂。您可以使用模块解析代码:
import ast
with open("mymod.py", "r") as fd:
module_ast = ast.parse("".join(fd.readlines()))
然后,您将遍历ast(
module_ast
),并隔离MyClass
树节点。这个链接提供了一个修改python代码内联的方法,并展示了如何。您可以使用这些链接中的技术组合来隔离与MyClass
相关的ast
节点,并删除其余节点。但这最终会对mymod.py实际包含的内容做出一些假设。这在Python中是不可能的。您应该设计代码,使其在导入时没有副作用
另外,请注意,无论您对模块使用了多少次导入模块,模块只执行一次,因此在导入模块时依赖副作用是非常糟糕的
尽管如此,如果您需要的是使模块在导入时的行为与运行时的行为不同,那么您可以通过使用:
# module.py
# Code that will always run
...
if __name__ == "__main__":
# Code that will only run if you do python module.py
# Usually print statements, argument parsing...
...
在您的情况下,您将执行以下操作:
class MyClass():
def __init__(self):
print 'Hello'
[...]
if __name__ == "__main__":
print 'something'
a = MyClass()
通常的使用方法是:
def main():
# do stuff
if __name__ == "__main__":
main()
这在Python中是不可能的。您应该设计代码,使其在导入时没有副作用 另外,请注意,无论您对模块使用了多少次导入模块,模块只执行一次,因此在导入模块时依赖副作用是非常糟糕的 尽管如此,如果您需要的是使模块在导入时的行为与运行时的行为不同,那么您可以通过使用:
# module.py
# Code that will always run
...
if __name__ == "__main__":
# Code that will only run if you do python module.py
# Usually print statements, argument parsing...
...
在您的情况下,您将执行以下操作:
class MyClass():
def __init__(self):
print 'Hello'
[...]
if __name__ == "__main__":
print 'something'
a = MyClass()
通常的使用方法是:
def main():
# do stuff
if __name__ == "__main__":
main()
我相信这里最具Python风格的解决方案是从另一个Python文件导入类。为此,请将imp.load_source()替换为:
我相信这里最具Python风格的解决方案是从另一个Python文件导入类。为此,请将imp.load_source()替换为: 步骤1-使用以下代码创建文件
main.py
:
from MyFolder import MyClass
instance = MyClass()
# Do whatever you wanna do with the MyClass instance...
步骤2-在文件main.py
旁边创建文件夹MyFolder
步骤3-将文件mymod.py
重命名为\uu init\uuuuuuuuuuuuuupy
,并将其放入文件夹MyFolder
步骤1-使用以下代码创建文件main.py
:
from MyFolder import MyClass
instance = MyClass()
# Do whatever you wanna do with the MyClass instance...
步骤2-在文件main.py
旁边创建文件夹MyFolder
步骤3-将文件mymod.py
重命名为\uuu init\uuuuuuuuuuuuupy
,并将其放入文件夹MyFolder
中
我不确定您是否能够完成您想要的任务(无需跨越重重障碍和反省模块的源代码)。如果您想隔离模块初始化,我建议将代码分为多个模块,并且只导入您想要的模块。我不确定您是否能够完成您想要的功能