我已经看到很多人从模块中提取所有类的例子,通常是这样的:
# foo.py
class Foo:
pass
# test.py
import inspect
import foo
for name, obj in inspect.getmembers(foo):
if inspect.isclass(obj):
print obj
Run Code Online (Sandbox Code Playgroud)
真棒.
但我无法找到如何从当前模块中获取所有类.
# foo.py
import inspect
class Foo:
pass
def print_classes():
for name, obj in inspect.getmembers(???): # what do I do here?
if inspect.isclass(obj):
print obj
# test.py
import foo
foo.print_classes()
Run Code Online (Sandbox Code Playgroud)
这可能是非常明显的事情,但我找不到任何东西.谁能帮我吗?
我想知道如何检查变量是否是一个类(不是实例!).
我已经尝试使用该函数isinstance(object, class_or_type_or_tuple)来执行此操作,但我不知道类将具有什么类型.
例如,在以下代码中
class Foo: pass
isinstance(Foo, **???**) # i want to make this return True.
Run Code Online (Sandbox Code Playgroud)
我试图取代" class"与??? ,但我意识到这class是python中的关键字.
有没有办法将所有类从python模块初始化为无名对象列表?
示例
我有一个模块rules,其中包含类Rule中的所有子类.因此,我确信他们都将实现一个方法,run()并且将具有name将在调用期间生成的属性__init__
我想有一个从这些类动态启动的对象列表.通过动态初始化,我的意思是它们不必明确命名.
问题是:
是否可以遍历模块中的所有类?
可以启动无名对象吗?
我目前正在编写一个应用程序,允许用户通过"插件"类型架构扩展它.他们可以根据我提供的BaseClass对象编写其他python类,并根据各种应用程序信号加载这些类.在启动应用程序之前,作为插件加载的类的确切数量和名称是未知的,但仅在启动时加载一次.
在我研究解决这个问题的最佳方法的过程中,我提出了两个常见的解决方案.
选项1 - 使用imp,pkgutil等滚动自己.
例如,请参阅此答案或此答案.
选项2 - 使用插件管理器库
随机选择一对
我的问题是-在应用程序必须以加载新的插件重新启动条件-是否有过什么灵感来自上述方法的任何利益这个苏答案和这一个,如:
import inspect
import sys
import my_plugins
def predicate(c):
# filter to classes
return inspect.isclass(c)
def load_plugins():
for name, obj in inspect.getmembers(sys.modules['my_plugins'], predicate):
obj.register_signals()
Run Code Online (Sandbox Code Playgroud)
与上述方法相比,这种方法有任何缺点吗?(除了所有插件必须在同一个文件中)谢谢!
编辑
评论请求进一步的信息...我能想到的唯一额外的事情是插件使用闪烁库来提供他们订阅的信号.每个插件可以订阅不同类型的不同信号,因此必须具有其自己的特定"寄存器"方法.
我有一系列用于对数据进行分类的函数.每个函数都传递相同的输入.该系统的目标是能够随意放入新的分类功能,而无需进行任何调整.
为此,我使用了classes_in_module从这里取消的功能.然后,将在每个输入上运行一个python文件中的每个分类器.
但是,我发现将分类器实现为类或函数是kludgy.类意味着实例化和执行,而函数缺乏干净的内省以允许我查询名称或使用继承来定义公共值.
这是一个例子.一,类实现:
class AbstractClassifier(object):
@property
def name(self):
return self.__class__.__name__
class ClassifierA(AbstractClassifier):
def __init__(self, data):
self.data = data
def run(self):
return 1
Run Code Online (Sandbox Code Playgroud)
然后可以以这种方式使用它,假设它classifier_list是classes_in_module包含ClassifierA在其他文件中的文件的输出:
result = []
for classifier in classifier_list:
c = classifier(data)
result.append(c.run())
Run Code Online (Sandbox Code Playgroud)
然而,这似乎有点傻.这个类显然是静态的,并不需要维护自己的状态,因为它被使用一次并被丢弃.分类器实际上是一个函数,但是我失去了拥有共享name属性的能力- 我将不得不使用丑陋的内省技术sys._getframe().f_code.co_name并为每个分类器函数复制该代码.分类器之间的任何其他共享属性也将丢失.
你怎么看?我应该接受这种错误使用课程吗?或者,还有更好的方法?
我的问题有点类似于这个问题; 它涉及对象方法而不是模块内容.我想知道我是否可以使用该inspect模块来获取仅在我询问的类中定义的方法,而不是它的父级.
我需要这个,因为我的子类定义了'宏'方法,它在更高的抽象级别访问父方法,我不希望用户不得不担心在继承中一直定义的低级方法树.
这是一个简化的例子:
class Foo(object):
def __init__(self): pass
def f1(self): return 3
def f2(self): return 1
class Bar(Foo):
def __init__(self): Foo.__init__(self)
def g1(self): return self.f1() + self.f2()
def g2(self): return self.f1() - self.f2()
import inspect
inspect.getmembers(Bar, inspect.ismethod)
Run Code Online (Sandbox Code Playgroud)
输出:
[('__init__', <unbound method Bar.__init__>),
('f1', <unbound method Bar.f1>),
('f2', <unbound method Bar.f2>),
('g1', <unbound method Bar.g1>),
('g2', <unbound method Bar.g2>)]
Run Code Online (Sandbox Code Playgroud)
用户不需要知道或关心fs 的存在,因为她只对gs 有兴趣.(当然,这个输出在绝大多数上下文中都是有意义的,因为所有这些方法在实例化时都会被绑定到对象.)对于一个长继承树,返回的列表可以变得很长并且充满了所有的东西.与用户无关.
我怎样才能得到它离开f1并f2关闭这个名单?是否有类似于__module__类中定义的方法的属性?更好的是,是否可以使用实例 …
有没有办法忽略python模块中的导入函数?
使用以下模块module.py时:
from inspect import getmembers, isfunction
import foo
def boo():
foo()
def moo():
pass
funcs = [mem[0] for mem in getmembers(module, isfunction)]
Run Code Online (Sandbox Code Playgroud)
funcs等于:(['boo','moo', 'foo']包括导入的函数“ foo”)
我希望['boo', 'moo']仅包含funcs 。