Python:inspect.ismethod 如何工作?
我正在尝试获取类中所有方法的名称。 在测试检查模块如何工作时,我通过 obj = MyClass.__dict__['mymethodname'] 提取了我的方法之一。
但现在 inspect.ismethod(obj)
返回 False
而 inspect.isfunction(obj)
返回 True
,并且我不明白为什么。是否有一些奇怪的方法将方法标记为我不知道的方法?我认为这只是它在类中定义并以 self 作为其第一个参数。
I'm trying to get the name of all methods in my class.
When testing how the inspect module works, i extraced one of my methods by obj = MyClass.__dict__['mymethodname']
.
But now inspect.ismethod(obj)
returns False
while inspect.isfunction(obj)
returns True
, and i don't understand why. Is there some strange way of marking methods as methods that i am not aware of? I thought it was just that it is defined in the class and takes self
as its first argument.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您正在看到 Python 幕后机制的一些影响。
当您编写
f = MyClass.__dict__['mymethodname']
时,您将获得“mymethodname”的原始实现,这是一个普通函数。要调用它,需要传入一个额外的参数,类实例。当您编写
f = MyClass.mymethodname
(请注意 mymethodname 后面没有括号)时,您将获得 MyClass 类的未绑定方法,它是包装了您在上面获得的原始函数。要调用它,需要传入一个额外的参数,类实例。当您编写
f = MyClass().mymethodname
(请注意,我在获取 MyClass 类的方法之前创建了一个 MyClass 类的对象),您将获得 MyClass 类实例的绑定方法。您不需要向其传递额外的类实例,因为它已经存储在其中。要通过以字符串形式给出的名称获取包装方法(绑定或未绑定),请使用
getattr
,如 gnibbler。例如:或
You are seeing some effects of the behind-the-scenes machinery of Python.
When you write
f = MyClass.__dict__['mymethodname']
, you get the raw implementation of "mymethodname", which is a plain function. To call it, you need to pass in an additional parameter, class instance.When you write
f = MyClass.mymethodname
(note the absence of parentheses after mymethodname), you get an unbound method of class MyClass, which is an instance ofMethodType
that wraps the raw function you obtained above. To call it, you need to pass in an additional parameter, class instance.When you write
f = MyClass().mymethodname
(note that i've created an object of class MyClass before taking its method), you get a bound method of an instance of class MyClass. You do not need to pass an additional class instance to it, since it's already stored inside it.To get wrapped method (bound or unbound) by its name given as a string, use
getattr
, as noted by gnibbler. For example:or
使用 源
第一个参数是 < code>self 只是按照惯例。通过从类的字典中按名称访问方法,您将绕过绑定,因此它看起来是一个函数而不是方法
如果您想按名称访问该方法,请使用
Use the source
The first argument being
self
is just by convention. By accessing the method by name from the class's dict, you are bypassing the binding, so it appears to be a function rather than a methodIf you want to access the method by name use
好吧,你的意思是
obj.mymethod
是一个方法(隐式传递self
),而Klass.__dict__['mymethod']
是一个功能?基本上,Klass.__dict__['mymethod'] 是“原始”函数,可以通过称为描述符的东西将其转换为方法。这意味着类上的每个函数都可以是普通函数和方法,具体取决于您访问它们的方式。这就是 Python 中类系统的工作方式,而且很正常。
如果您想要方法,则不能使用
__dict__
(无论如何您都不应该这样做)。要获取所有方法,您应该执行inspect.getmembers(Klass_or_Instance,inspect.ismethod)
您可以阅读详细信息在这里,关于这个的解释在“用户定义的方法”下。
Well, do you mean that
obj.mymethod
is a method (with implicitly passedself
) whileKlass.__dict__['mymethod']
is a function?Basically
Klass.__dict__['mymethod']
is the "raw" function, which can be turned to a method by something called descriptors. This means that every function on a class can be both a normal function and a method, depending on how you access them. This is how the class system works in Python and quite normal.If you want methods, you can't go though
__dict__
(which you never should anyways). To get all methods you should doinspect.getmembers(Klass_or_Instance, inspect.ismethod)
You can read the details here, the explanation about this is under "User-defined methods".
从对 @THC4k 的答案的评论来看,OP 似乎想要区分内置方法和纯 Python 代码中定义的方法。用户定义的方法是
types.MethodType
,但内置方法不是。您可以获得各种类型,如下所示:
打印:
From a comment made on @THC4k's answer, it looks like the OP wants to discriminate between built-in methods and methods defined in pure Python code. User defined methods are of
types.MethodType
, but built-in methods are not.You can get the various types like so:
which prints:
您可以使用 dir 获取可用方法/属性/等的名称,然后迭代它们以查看哪些是方法。像这样:
我期待有一个更干净的解决方案,但如果没有其他人提出一个解决方案,这可能是您可以使用的东西。我希望我不必使用类的实例来使用 getattribute。
You could use dir to get the name of available methods/attributes/etc, then iterate through them to see which ones are methods. Like this:
I'm expecting there to be a cleaner solution, but this could be something you could use if nobody else comes up with one. I'd like if I didn't have to use an instance of the class to use getattribute.