从同一模块动态实例化类会导致main运行两次

时间:2014-09-30 21:25:55

标签: python python-2.7

我有一个名为dynamic_cls_ex.py的模块和两个名为FooButtonBarButton的类。我使用下面的代码从字符串动态实例化我感兴趣的类。

问题:我使用__import__导入模块,导致main运行两次。 这是我的基本理解。请随时向我提供更好的解释

的实际情况
# !/usr/bin/python

class FooButton(object):
    def __init__(self):
        print 'I am a foo button'

class BarButton(object):
    def __init__(self):
        print 'I am a bar button'


method = 'Foo'
class_name = '%sButton' % method
module = __import__('dynamic_cls_ex')
Button = getattr(module, class_name)
Button()


# OUTPUT:
# >> I am a foo button
# >> I am a foo button

如何动态实例化一个类而无需导入我当前正在运行的模块?

3 个答案:

答案 0 :(得分:3)

嗯,你还没有指定dynamic_cls_ex.py中的内容,但我认为它有一些实际运行的顶级代码(这就是你正在调用main 1}}功能,我认为)。

只要其封闭的python文件本身在解释器的顶层运行,或者导入时,就会运行此代码(使用__import__时,您明确规避检查以不重新加载已存在模块)。

但是你可以通过检查__main__ - &#34来强制代码仅在顶级实际运行时运行;此模块代表解释器主程序的(否则是匿名的)范围执行&#34 ;.因此,如果您将顶级代码包装在if __name__ == "__main__":中,它将仅从主程序运行,而不是在导入时运行。

另请参阅此处的What does if __name__ == "__main__": do?

答案 1 :(得分:0)

if __name__ == '__main__'添加一个保护并放置全局范围内的代码会阻止代码运行两次。

当我运行以下代码时:

print __name__
module = __import__('dynamic_cls_ex')

# I get:
# >> __main__
# >> dynamic_cls_ex

所以我改变了代码以获得像上面片段一样的警卫,我得到了以下输出,这说明了为什么警卫工作,并且我没有得到任何更多重复。

# placed below FooButton BarButton class definitions

print __name__

if __name__ == '__main__':
    method = 'Foo'
    class_name = '%sButton' % method
    module = __import__('dynamic_cls_ex')
    Button = getattr(module, class_name)
    Button()

# Output:
# >> __main__
# >> dynamic_cls_ex
# >> I am a foo button

答案 2 :(得分:-1)

您可以使用globals()函数来获取具有全局名称绑定的字典。然后你可以访问这本词典来获得你的课程。