[英]Dynamically load module with Inheritance
我知道有很多关于该主题的文章,但是出于某种原因,我无法理解或至少实现它。 以下是我要尝试执行的一些示例代码。
基类:
class Animal(object):
def __init__(self, age):
self._age = age
def getAge(self):
return self._age
def speak(self):
raise NotImplementedError()
def speak_twice(self):
self.speak()
self.speak()
子类
from Animal import Animal
class Dog(Animal):
def speak(self):
print "woff!"
测试代码
mod = __import__("Dog")
spot = mod(5)
运行测试代码后,我得到此错误:
Traceback (most recent call last):
File "C:~test.py", line 2, in <module>
spot = mod(5)
TypeError: 'module' object is not callable
所以基本上我的问题是如何动态加载模块并正确初始化它们?
编辑:
直到运行时我才知道子类
您必须导入模块本身,然后获取其类成员。 您不能只导入该类。 假设您的子类在pythonpath中可访问的文件中为“ animal”:
mod = __import__('animal')
spot = mod.Dog(5)
导入模块时,解释器首先查看sys.modules
是否存在具有该名称的模块,然后如果在该模块中找不到该模块,它将在pythonpath中搜索以查找与给定名称匹配的软件包或模块。 如果找到时,它将解析其中的代码,从中构建一个模块对象,将其放置在sys.modules
,然后将该模块对象返回到调用范围以绑定到给定的名称(在给定的名称中导入)命名空间。 然后,可以将模块作用域中模块中的所有项目(类,变量,函数)(不嵌套在代码中的其他内容中)用作该模块实例的成员。
编辑:
为了回应您的评论,真正的问题是您试图动态查找模块的属性,而不是尝试动态导入任何内容。 最直接的方法是:
import sub_animal
getattr(sub_animal, 'Dog')
但是,如果您尝试根据某些条件动态确定要初始化的类,则可能需要阅读factory模式 ,还可能需要decorator
甚至metaclass
es ,以便可以将子类自动动态添加到工厂。
class AnimalFactory(type):
animal_classes = {}
def __new__(cls, name, bases, attrs):
new_class = super(AnimalFactory, cls).__new__(cls, name, bases, attrs)
AnimalFactory.animal_classes[name] = new_class
return new_class
@classmethod
def build(cls, name, *args, **kwargs):
try:
klass = cls.animal_classes[name]
except KeyError:
raise ValueError('No known animal %s' % name)
return klass(*args, **kwargs)
class Animal(object):
__metaclass__ = AnimalFactory
def __init__(self, age):
self.age = age
def speak(self):
raise NotImplementedError()
# As long as the file it is implemented in is imported at some point,
# the following can be anywhere
class Dog(Animal):
def speak(self):
return 'woof'
# And then to use, again, anywhere
new_animal = AnimalFactory.build('Dog', 5)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.