After learning programming for so long, I still can't tell what is a method and what is a function? ...

WeChat search "Python cat", a public account worthy of star

There are two very basic concepts in programming languages, namely method (method) and function (function). If you have reached the elementary/entry-level level of programming, then you must have an initial answer in mind.

Maybe you already have the answer in your heart

In addition to the correct form and content such as input parameters, return values, and anonymous functions, you may say that "functions are defined outside the class, and methods are defined inside the class and bound to the class".

Is there any problem with this statement? Of course there is! Otherwise, I will not write this article specifically. This article will mainly clarify this issue.

In the standard library inspect, it provides two introspection functions, namely ismethod() and isfunction(), which can be used to judge what is a method and what is a function.

Therefore, this article wants to study these two functions first, and see how Python handles the concept of methods/functions.

Regarding their usage, let's look at the simplest example:

The results of the operation are "True" and "False", indicating that the test() we defined is a function, not a method.

These two functions can also be used to detect themselves, and it is not difficult to verify that they are both functions:

So, the next question is: How do the two functions of the inspect library work?

Let's take a look at the implementation code in inspect:

In the source code, we saw the isinstance() function, which is mainly used to judge whether an object (object) is an instance (instance) of a certain class (class).

We also saw types.FunctionTypeand types.MethodType, which refer to the target class. Continue to click in to see the source code:

# 摘自 types.py
def _f(): pass
FunctionType = type(_f)

class _C:
    def _m(self): pass
MethodType = type(_C()._m)

Here just define two empty _f() and _m(), and then use the built-in type() function. Therefore, we can take them out and see the true face of Mount Lu:

Combing their relationship, we can get:

After simplification, we found that the two most critical issues are: How does the type() function determine whether an object is a function or a method class? How does the instance() function determine that an object is an instance of a certain class?

These two built-in functions are implemented in C language, and I am not going to go into details here...

However, let's look back at the comments in inspect and notice some clues:

  • isfunction() determines that it is a user-defined function (user-defined function), which has attributes such as __doc__, __name__, etc.

  • ismethod() determines that it is an instance method (instance method), which has some attributes of a function, most notably a __self__ attribute

Or comments are more useful, so we can get the following inferences:

1. Non-user-defined functions, that is, built-in functions, are not "functions" (FunctionType) in the eyes of isfunction()!

Let's verify len(), dir() and range():

In fact, they have their own classes (BuiltinFunctionType, BuiltinMethodType):

In particular, it should be noted that the built-in functions are builtin_function_or_methodall types, but range(), type(), list(), etc. look like functions, but they are not:

(PS: Regarding this point, I mentioned it in this article, so I won’t expand it.)

2. A static method of a class is not a method (MethodType) in the eyes of ismethod()!

After creating an instance of the class, look again:

It can be seen that, except classmethod, only instance methods of class instances will be judged true by ismethod()! And a static method, whether bound to a class or an instance, is not a "method"!

Do you find it incredible (or a little confused)?

Well, back to the question at the beginning of this article, let's make a summary at the end.

If the two functions of the inspect library are used as the basis for judgment, the "method and function" in Python has a certain narrow meaning. They don't count built-in functions when determining what a function is. At the same time, when judging what a method is, not all defined inside the class are counted, but only class methods and instance methods bound to instances are considered "methods".

Maybe you will say that the two judgment functions of inspect are not credible, built-in functions should also be regarded as "functions", and all methods in the class should be regarded as "methods".

I admit that this statement is acceptable in a broad sense, after all, what we have always called "XX function" and "XX method".

However, theories and broad concepts are only for the convenience of people's communication and understanding, while the code implementation is the essential difference. In other words, when Python actually distinguishes "methods and functions", it is not a simple statement at the beginning of the article, and there are more details worthy of attention.

After reading this article, what do you think? Welcome to communicate together.

High-quality articles, recommended reading:

Why create a class that cannot be instantiated?

A regular expression article worthy of collection

27 questions about Python design and history

How to protect your Python code (1) - existing encryption schemes

Guess you like

Origin blog.csdn.net/chinesehuazhou2/article/details/105424145