我有一个名为dynamic_cls_ex.py
的模块和两个名为FooButton
和BarButton
的类。我使用下面的代码从字符串动态实例化我感兴趣的类。
问题:我使用__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
如何动态实例化一个类而无需导入我当前正在运行的模块?
答案 0 :(得分:3)
嗯,你还没有指定dynamic_cls_ex.py
中的内容,但我认为它有一些实际运行的顶级代码(这就是你正在调用main
1}}功能,我认为)。
只要其封闭的python文件本身在解释器的顶层运行,或者导入时,就会运行此代码(使用__import__
时,您明确规避检查以不重新加载已存在模块)。
但是你可以通过检查__main__
- &#34来强制代码仅在顶级实际运行时运行;此模块代表解释器主程序的(否则是匿名的)范围执行&#34 ;.因此,如果您将顶级代码包装在if __name__ == "__main__":
中,它将仅从主程序运行,而不是在导入时运行。
答案 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()函数来获取具有全局名称绑定的字典。然后你可以访问这本词典来获得你的课程。