我有代码:
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'类。其他事情是不可取的。
答案 0 :(得分:3)
您可以像mymod.py
那样将结束行包装起来:
if __name__ == "__main__":
print 'something'
a = MyClass()
结果将是这些行仅在mymod.py
作为脚本执行时执行,而不是作为模块导入。请参阅Python文档中的executing modules as scripts。
但请注意,如果您在mymod.py
中定义了其他类,则仍会由imp.load_source
导入。
修改:由于您无法修改mymod.py
,因此解决方案变得更加复杂。您可以使用ast模块来解析代码:
import ast
with open("mymod.py", "r") as fd:
module_ast = ast.parse("".join(fd.readlines()))
然后,您将遍历ast(module_ast
)并隔离MyClass
树节点。此链接提供example内联修改python代码,这显示如何analyse code。您可以使用这些链接中的技术组合来隔离与ast
相关的MyClass
节点,并删除其余节点。但这最终会对mymod.py
实际包含的内容做出一些假设。
答案 1 :(得分:3)
这在Python中是不可能的。您应该设计代码,使其在导入时没有副作用。
另外,请注意,模块只执行一次,无论您使用import module
多少次,所以依赖非常糟糕的主意关于模块导入的副作用。
尽管如此,如果您需要的是让您的模块在导入时的行为与运行时的行为不同,那么您可以通过使用以下方式实现该目标:
# 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()
答案 2 :(得分:1)
class MyClass():
def __init__(self):
print 'Hello'
[...]
if __name__ == '__main__':
print 'something'
a = MyClass()
if __name__
块中的所有语句只有在直接执行该模块时才会执行,而不是在导入模块时执行。
答案 3 :(得分:0)
我相信这里最pythonic的解决方案是从你的其他Python文件中导入类。为此,请将imp.load_source()替换为:
from mymod import MyClass
答案 4 :(得分:0)
第1步 - 使用以下代码创建文件main.py
:
from MyFolder import MyClass
instance = MyClass()
# Do whatever you wanna do with the MyClass instance...
第2步 - 在文件MyFolder
旁边创建文件夹main.py
。
第3步 - 将文件mymod.py
重命名为__init__.py
,并将其放在文件夹MyFolder
内。
答案 5 :(得分:0)