当我尝试使用getattr动态加载类时,我得到的是一个模块类而不是真正的类。你知道吗
module = importlib.import_module("bigpackage.animals")
class_ = getattr(module, "dog_input")
pprint(type(class_))
# Outputs <class 'module'>
我的狗输入类:
from bigpackage.animals.animal import AbstractAnimal
class DogInput(AbstractAnimal):
def __init__(self):
self.b = "bb"
@property
def name(self):
prefix = super(DogInput, self).name
return prefix + "Name"
我有以下套餐:
大包装(package)
TLDR:您只加载模块,而不是所包含的类。你知道吗
请注意,对于Python来说,包和模块大多只是任意的名称空间。类与其包含的模块之间没有强映射。让一个模块
dog_input
实现类DogInput
不会使一个成为另一个的别名DogInput
是dog_input
的常规成员,后者可能包含任意其他类和值。你知道吗当您知道类位于何处时,最简单的方法是导入模块,然后从中获取类:
如果只有类名,但有一致的命名方案,则可以从类名中提取模块名。看这个question on converting CamelCase to lower-case-with-underscores。你知道吗
注意,在Python中,这通常是不受欢迎的。您隐式地依赖于每一个知道您的命名约定的维护人员——至少可以说,这很容易打破。你知道吗
你也可以让人们提供一个限定名
dog_input.DogInput
,而不是仅仅DogInput
。这取决于您允许多少嵌套(模块和/或内容),从简单到非常复杂。你知道吗这是一种非常强大但也很脆弱的方法。如果输入来自信任的、有经验的、需要很大灵活性的用户,就可以使用它。因为它可能允许执行任意代码,所以不要将其用于公共服务。你知道吗
如果存在一组固定的/已知的允许类,则最容易显式地对它们进行索引。这为您提供了实现灵活性和安全性。你知道吗
这为您提供了最大的灵活性,但限制了用户可以做什么。如果将来需要更改代码,并且用户是外部的,那么它是理想的。注意,可以动态地构建映射,例如通过decorator或entry_points注册类。你知道吗
相关问题 更多 >
编程相关推荐