Python-如何查询定义方法的类? [英] Python - How can I query the class in which a method is defined?

查看:107
本文介绍了Python-如何查询定义方法的类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题有点类似于

这是一个简化的示例:

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感兴趣. (当然,此输出在绝大多数情况下都是有意义的,因为所有这些方法都将在实例化时绑定到该对象.)对于长继承树,返回的列表可能会很长,并且充满了与用户无关.

如何将f1f2排除在此列表之外?类中定义的方法的__module__属性是否等效?更好的是,是否可以使用 instance 方法做同样的事情?

解决方案

方法具有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数据模型中. >

My question is somewhat similar to this one; it concerns object methods rather than module contents. I want to know if I can use the inspect module to get the methods defined only in the class I'm asking about, and not its parent(s).

I need this because my child class defines 'macro' methods, which accesses the parent's methods at a higher level of abstraction, and I don't want the user to have to worry about the lower-level methods defined all the way up the inheritance tree.

Here is a simplified example:

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)

Output:

[('__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>)]

The user need not know or care about the existence of the fs since she's only ever going to be interested in the gs. (Of course, this output makes sense in the vast majority of contexts, since all these methods will be bound to the object when it is instantiated.) For a long inheritance tree, the returned list can get very long and full of things that aren't relevant to the user.

How can I get it to leave f1 and f2 off this list? Is there an equivalent to the __module__ attribute for the methods defined in classes? Better still, is it possible to do the same thing with instance methods?

解决方案

Methods have an im_class attribute, that points to the class in question. You can use that filter on functions that are members of the class:

inspect.getmembers(Bar,
    lambda m: inspect.ismethod(m) and m.__func__ in m.im_class.__dict__.values())

This gives you:

[
    ('__init__', <unbound method Bar.__init__>),
    ('f1', <unbound method Bar.f1>), 
    ('f2', <unbound method Bar.f2>)
]

Of course, you can just bypass getmembers altogether then:

[m for m in Bar.__dict__.values() if inspect.isfunction(m)]

gives:

[<function __init__ at 0x100a28de8>, <function g1 at 0x100a28e60>, <function g2 at 0x100a28ed8>]

This applies to bound or unbound methods, they have same .__func__ (or im_func, the old name) attribute. The difference between bound and unbound is the value of the .__self__ attribute (None when unbound).

These "secret" attributes are all documented in the Python Data Model.

这篇关于Python-如何查询定义方法的类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆