Python的 - 我如何可以查询其定义一个方法的类?(Python - How can I que

2019-09-21 04:09发布

我的问题是有点类似这一个 ; 它涉及对象的方法,而不是模块的内容。 我想知道我是否可以使用inspect模块得到只有在我询问的类中定义的方法,而不是它的父(S)。

我需要这个,因为我的子类定义了“宏”的方法,它访问父的方法,在更高的抽象水平,我不希望用户不必担心定义一路继承较低级别的方法树。

下面是一个简化的例子:

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秒。 (当然,这个输出是有道理在绝大多数环境中,因为所有这些方法将被绑定到当它被实例化的对象。)在相当长的继承树,返回的列表可能会很长,充满东西AREN “T与用户相关。

我怎样才能得到它离开f1f2关闭这个名单? 是否有一个相当于__module__在类中定义的方法属性? 更妙的是,是否有可能用实例方法是一回事吗?

Answer 1:

方法有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 ,旧名)属性。 结合和未结合之间的差异是的值.__self__属性(无时未结合的)。

这些“秘密”的属性都记录在Python的数据模型 。



Answer 2:

希望有人将与更好的解决方案,但对于一起走:

foo_members = inspect.getmembers(Foo,inspect.ismethod)
bar_members = inspect.getmembers(Bar,inspect.ismethod)

set(bar_members) - set(foo_members)

当然,在实际情况下,可能需要通过走路Bar.__bases__真正摆脱你不想要的一切。

例如:

set(bar_members) - set(sum([inspect.getmembers(base,inspect.ismethod) for base in Bar.__bases__],[]))


文章来源: Python - How can I query the class in which a method is defined?