Python中的函数(function)与方法(method)使用详解

Written by

in

文章目录
  • 在标准库inspect 中,它提供了两个自省的函数,即 ismethod() 和 isfunction(),可以用来判断什么是方法,什么是函数。 import inspect def test1(): print(‘这是方法还是函数?’) print(inspect.isfunction(test1)) # True print(inspect.ismethod(test1)) # False 运行的结果分别是“True”和“False”,表明我们所定义的 test() 是一个函数,而不是一个方法。 注意:不能用这种方式,这种方式会调用函数 import inspect def test1(): print(‘这是方法还是函数?’) print(inspect.isfunction(test1())) # 输出结果 这是方法还是函数? False
  • 这两个函数也可以用来检测自身,不难验证出它们都是一种函数 import inspect print(inspect.isfunction(inspect.ismethod)) # True print(inspect.isfunction(inspect.isfunction)) # True 那么,inspect 库的两个函数是什么工作原理呢? 看看源码,将鼠标光标处放在要查看的内容上,按住Ctrl并单击鼠标左键,进入源码查看 通过 isfunction() 和 ismethod() 的注释,我们可以得到以下结论: 非用户定义的函数,即内置函数,在 isfunction() 眼里并不是“函数”(FunctionType)! 下面验证一下 len()、 range(): import inspect print(inspect.isfunction(len)) # False print(inspect.isfunction(range)) # False 可以发现,它们的本质并不是函数,事实上,它们有专属的类别(BuiltinFunctionType、BuiltinMethodType) print(type(len)) 输出结果: <class ‘builtin_function_or_method’> 内置函数都是builtin_function_or_method 类型 一个类的静态方法,在 ismethod() 眼里并不是方法(MethodType)! class MyTest(): @classmethod def cls_func(cls): pass def ins_func(self): pass @staticmethod def sta_func(): pass print(inspect.ismethod(MyTest.cls_func)) # True print(inspect.ismethod(MyTest.ins_func)) # False print(inspect.ismethod(MyTest.sta_func)) # False 创建了类的实例后,再看看 test = MyTest() print(inspect.ismethod(test.cls_func)) # True print(inspect.ismethod(test.ins_func)) # True print(inspect.ismethod(test.sta_func)) # False 可以看出,除了 classmethod 之外,只有类实例的实例方法,才会被 ismethod() 判定为真!而静态方法,不管绑定在类还是实例上,都不算是“方法”! 在源码中,出现了 isinstance() 函数,它主要用于判断一个对象(object)是否是某个类(class)的实例(instance)。 还出现了 types.FunctionType 及types.MethodType ,它们指的就是目标类。继续点进去看源码 经过简化处理后,最关键是在于:通过type() 函数判断出一个对象是 function 或 method 类,instance() 函数判断出一个对象是否为某个类的实例 所以 isfunction() 判断出的是用户定义的函数(user-defined function), 它拥有__doc__、__name__ 等等属性 ismethod() 判断出的是实例方法(instance method), 它拥有函数的一些属性,最特别的是还有一个 __self__ 属性 若以 inspect 库的两个函数为判断依据,则 Python 中的“方法与函数”具有一定的狭义性。 在判断什么是函数时,它们并不把内置函数计算在内。同时,在判断什么是方法时,并非定义在类内部的都算,而是只有类方法及绑定了实例的实例方法才算是“方法”。 也许你会说,inspect 的两个判断函数并不足信,规矩是写死的,也有不灵活的时候,内置函数也应该算是“函数”,类里面的所有方法都应该算是“方法”。 这种说法在广义上是可接受的,毕竟我们一直叫的就是“XX函数”、而不会去说“XX方法”。 但是,理论和广义概念只是方便人们的沟通理解,而代码实现才是本质的区别。 也就是说,Python 在实际区别“方法与函数”时,文中开头所说:“函数就是定义在类外面的,而方法就是定义在类里面的,跟类绑定的”,这句话并没有错,但其中的细节还是值得关注的。
  • 以上为个人经验,希望能给大家一个参考,也希望大家多多支持风君子博客。 您可能感兴趣的文章: Python内置函数之def function_name函数解读 详解Python中的偏函数(Partial Functions) python人工智能tensorflow常用激活函数Activation Functions Python偏函数Partial function使用方法实例详解 Python内置函数之classmethod函数使用详解 Python内置函数之staticmethod函数使用及说明 Python中@classmethod和@staticmethod的区别
  • 目录
    • 判断是函数(function)还是方法(method)
    • inspect.ismethod() 与 inspect.isfunction()
    • 总结

    在编程语言中有两个很基础的概念,即方法(method)和函数(function)。

    除去入参、返回值、匿名函数之类的正确的形式内容之外,我们一般都会这样说:“函数就是定义在类外面的,而方法就是定义在类里面的,跟类绑定的”

    深究一下

    在标准库inspect 中,它提供了两个自省的函数,即 ismethod() 和 isfunction(),可以用来判断什么是方法,什么是函数。

    import inspect
    
    def test1():
        print('这是方法还是函数?')
    
    print(inspect.isfunction(test1)) # True
    print(inspect.ismethod(test1)) # False
    

    运行的结果分别是“True”和“False”,表明我们所定义的 test() 是一个函数,而不是一个方法。

    注意:不能用这种方式,这种方式会调用函数

    import inspect
    
    def test1():
        print('这是方法还是函数?')
    
    
    print(inspect.isfunction(test1()))
    
    # 输出结果
    这是方法还是函数?
    False
    

    这两个函数也可以用来检测自身,不难验证出它们都是一种函数

    import inspect
    
    print(inspect.isfunction(inspect.ismethod))   # True
    print(inspect.isfunction(inspect.isfunction))   # True
    

    那么,inspect 库的两个函数是什么工作原理呢?

    看看源码,将鼠标光标处放在要查看的内容上,按住Ctrl并单击鼠标左键,进入源码查看

    通过 isfunction() 和 ismethod() 的注释,我们可以得到以下结论:

    • 非用户定义的函数,即内置函数,在 isfunction() 眼里并不是“函数”(FunctionType)!

    下面验证一下 len()、 range():

    import inspect
    
    print(inspect.isfunction(len)) # False
    
    print(inspect.isfunction(range)) # False
    

    可以发现,它们的本质并不是函数,事实上,它们有专属的类别(BuiltinFunctionType、BuiltinMethodType)

    print(type(len))
    输出结果:
    <class 'builtin_function_or_method'>
    

    内置函数都是builtin_function_or_method 类型

    • 一个类的静态方法,在 ismethod() 眼里并不是方法(MethodType)!
    class MyTest():
    
        @classmethod
        def cls_func(cls):
            pass
    
        def ins_func(self):
            pass
    
        @staticmethod
        def sta_func():
            pass
    
    print(inspect.ismethod(MyTest.cls_func))  # True
    print(inspect.ismethod(MyTest.ins_func))  # False
    print(inspect.ismethod(MyTest.sta_func))  # False
    
    

    创建了类的实例后,再看看

    test = MyTest()
    
    print(inspect.ismethod(test.cls_func))  # True
    print(inspect.ismethod(test.ins_func))  # True
    print(inspect.ismethod(test.sta_func))  # False
    

    可以看出,除了 classmethod 之外,只有类实例的实例方法,才会被 ismethod() 判定为真!而静态方法,不管绑定在类还是实例上,都不算是“方法”!

    在源码中,出现了 isinstance() 函数,它主要用于判断一个对象(object)是否是某个类(class)的实例(instance)。

    还出现了 types.FunctionType 及types.MethodType ,它们指的就是目标类。继续点进去看源码

    经过简化处理后,最关键是在于:通过type() 函数判断出一个对象是 function 或 method 类,instance() 函数判断出一个对象是否为某个类的实例

    所以

    isfunction() 判断出的是用户定义的函数(user-defined function), 
    它拥有__doc__、__name__ 等等属性
    
    ismethod() 判断出的是实例方法(instance method), 
    它拥有函数的一些属性,最特别的是还有一个 __self__ 属性
    

    若以 inspect 库的两个函数为判断依据,则 Python 中的“方法与函数”具有一定的狭义性。

    在判断什么是函数时,它们并不把内置函数计算在内。同时,在判断什么是方法时,并非定义在类内部的都算,而是只有类方法及绑定了实例的实例方法才算是“方法”。

    也许你会说,inspect 的两个判断函数并不足信,规矩是写死的,也有不灵活的时候,内置函数也应该算是“函数”,类里面的所有方法都应该算是“方法”。

    这种说法在广义上是可接受的,毕竟我们一直叫的就是“XX函数”、而不会去说“XX方法”。

    但是,理论和广义概念只是方便人们的沟通理解,而代码实现才是本质的区别。

    也就是说,Python 在实际区别“方法与函数”时,文中开头所说:“函数就是定义在类外面的,而方法就是定义在类里面的,跟类绑定的”,这句话并没有错,但其中的细节还是值得关注的。

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持风君子博客。

    您可能感兴趣的文章:

    • Python内置函数之def function_name函数解读
    • 详解Python中的偏函数(Partial Functions)
    • python人工智能tensorflow常用激活函数Activation Functions
    • Python偏函数Partial function使用方法实例详解
    • Python内置函数之classmethod函数使用详解
    • Python内置函数之staticmethod函数使用及说明
    • Python中@classmethod和@staticmethod的区别

    站内搜索