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

  • 不要编写自己的插件系统。他们已经太多了
  • 虽然理论上可以检查模块的AST,只提取所需的位,但实际上这会导致各种奇怪的情况,这是一个坏主意。不要这样做。要求插件的编写方式应确保导入插件时不会产生副作用
  • 不要编写自己的插件系统。他们已经太多了
  • 虽然理论上可以检查模块的AST,只提取所需的位,但实际上这会导致各种奇怪的情况,这是一个坏主意。不要这样做。要求插件的编写方式应确保导入插件时不会产生副作用

  • 我不确定您是否能够完成您想要的任务(无需跨越重重障碍和反省模块的源代码)。如果您想隔离模块初始化,我建议将代码分为多个模块,并且只导入您想要的模块。我不确定您是否能够完成您想要的功能