我的问题与this one有些相似;它涉及对象方法而不是模块内容。我想知道我是否可以使用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)
输出:
[('__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>)]
用户不需要知道或关心f
的存在,因为她只对g
感兴趣。 (当然,这个输出在绝大多数上下文中都是有意义的,因为所有这些方法在实例化时都会被绑定到对象。)对于一个长继承树,返回的列表可以变得很长并且充满了所有的东西。与用户相关。
如何让它离开此列表f1
和f2
?是否有类似于类中定义的方法的__module__
属性?更好的是,是否可以使用实例方法做同样的事情?
答案 0 :(得分:5)
方法有一个im_class
属性,指向有问题的类。您可以对属于该类成员的函数使用该过滤器:
inspect.getmembers(Bar,
lambda m: inspect.ismethod(m) and m.__func__ in m.im_class.__dict__.values())
这会给你:
[
('__init__', <unbound method Bar.__init__>),
('f1', <unbound method Bar.f1>),
('f2', <unbound method Bar.f2>)
]
当然,你可以完全绕过getmembers
:
[m for m in Bar.__dict__.values() if inspect.isfunction(m)]
给出:
[<function __init__ at 0x100a28de8>, <function g1 at 0x100a28e60>, <function g2 at 0x100a28ed8>]
这适用于绑定或未绑定方法,它们具有相同的.__func__
(或im_func
,旧名称)属性。 bound和unbound之间的区别是.__self__
属性的值(未绑定时为None)。
这些“秘密”属性都记录在Python Data Model。
中答案 1 :(得分:2)
希望有人会提出更好的解决方案,但是:
foo_members = inspect.getmembers(Foo,inspect.ismethod)
bar_members = inspect.getmembers(Bar,inspect.ismethod)
set(bar_members) - set(foo_members)
当然,在实际情况中,你可能需要走过Bar.__bases__
才能真正摆脱你不想要的一切。
e.g:
set(bar_members) - set(sum([inspect.getmembers(base,inspect.ismethod) for base in Bar.__bases__],[]))