先上结论:

  1. 函数(function)是Python中一个可调用对象(callable), 方法(method)是一种特殊的函数。
  2. 一个可调用对象是方法和函数,和这个对象无关,仅和这个对象是否与类或实例绑定有关(bound method)。
  3. 实例方法,在类中未和类绑定,是函数;在实例中,此实例方法与实例绑定,即变成方法。
  4. 静态方法没有和任何类或实例绑定,所以静态方法是个函数。
  5. 装饰器不会改变被装饰函数或方法的类型。
  6. 类实现__call__方法,其实例也不会变成方法或函数,依旧是类的实例。
  7. 使用callalble() 只能判断对象是否可调用,不能判断是不是函数或方法。
  8. 判断对象是函数或方法应该使用type(obj)。

下面,使用一些例子,对上述结论进行检测、验证。

测试的例子中,我们创建一个装饰器、一个函数及一个类,这个类包含:实例方法、类方法、静态方法及被装饰器装饰的方法。

完整代码: https://github.com/blackmatrix7/python-learning/blob/master/function_/method_func.py

def test_decorator(func):
"""
装饰器,测试使用,无功能
:param func:
:return:
"""
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper def the_function():
"""
函数
:return:
"""
pass class TheClass: def __call__(self, *args, **kwargs):
return self @classmethod
def class_method(cls):
"""
类方法
:return:
"""
pass def instance_method(self):
"""
实例方法
"""
return self @staticmethod
def static_method():
"""
静态方法
:return:
"""
pass @test_decorator
def decorated_func(self):
pass

先对类方法和实例方法的类型进行检测(注释部分为输出结果,下同)。

从运行结果上看,类方法和实例方法都是方法(method)。

同时,通过直接打印类方法和实例方法,可以得知它们都是绑定方法(bound method)。

    print('class_method type {type} '.format(type=type(TheClass.class_method)))
# class_method type <class_ 'method'>
print('instance_method type {type} '.format(type=type(the_class.instance_method)))
# instance_method type <class_ 'method'>
print(TheClass.class_method)
# <bound method TheClass.class_method of <class '__main__.TheClass'>>
print(the_class.instance_method)
# <bound method TheClass.instance_method of <__main__.TheClass object at 0x00000275DEB3FC50>>

如果仅通过上述运行结果,就得出类方法和实例方法都是方法,那么就错了。

再看下面的代码,同一个对象instance_method,之前还是方法(method),现在已经变成函数(function)。

    print('instance_method type {type} '.format(type=type(TheClass.instance_method)))
# instance_method type <class 'function'>
print(TheClass.instance_method)
# <function TheClass.instance_method at 0x00000275DEB3D840>

第二段代码,和第一段代码的不同之处:第一段代码是通过实例,去访问实例方法;而第二段代码,是通过类去访问实例方法。

同一个可调用对象,仅仅是访问的方式不同,就能从方法变为函数。

因为,在类中的实例方法,并没有和类建立绑定关系,所以它是方法。当类进行实例化时,会将实例方法,绑定到类创建出的实例上,此时实例方法与实例形成绑定关系,从函数变为方法。

所以,可以得到开头的第2、3条结论:

一个可调用对象是方法和函数,和这个对象无关,仅和这个对象是否与类或实例绑定有关(bound method)。

实例方法,在类中未和类绑定,是函数;在实例中,此实例方法与实例绑定,即变成方法。

接着对静态方法进行检测,有了之前的结论,就很容易理解为什么静态方法是函数而不是方法:因为它不会和类或实例进行绑定。

    print('static_method type {type} '.format(type=type(the_class.static_method)))
# static_method type <class_ 'function_'>
print('static_method type {type} '.format(type=type(TheClass.static_method)))
# static_method type <class 'function'>
print(TheClass.static_method, the_class.static_method, sep='\n')
# <function TheClass.static_method at 0x0000024BC5EAD950>
# <function TheClass.static_method at 0x0000024BC5EAD950>

而对于一个函数,因为不会和任何类或实例绑定(除非使用MethodType将函数绑定到某个实例上),必然不是方法。

    print('the_function type {type} '.format(type=type(the_function)))
# the_function type <class_ 'function_'>

对于装饰器,本身也不会改变被装饰对象的类型

    # 装饰器本身也是个函数
print('test_decorator type {type} '.format(type=type(test_decorator)))
# test_decorator type <class_ 'function_'> # 将装饰器装饰器到实例方法上
# 检查被装饰的方法的类型
print('decorated_func type {type} '.format(type=type(the_class.decorated_func)))
# decorated_func type <class_ 'method'>
# 从测试结果得知,装饰器不会影响被装饰方法或函数的类型

如果一个类,实现__call__方法,那么其实例会变为可调用对象,但这个这个实例依旧不是函数或方法

    # 如果类实现__call__方法
# 执行结果True 其实例变为可调用对象
print('class_instance callable {callable} '.format(callable=callable(the_class)))
# 实例的类型依旧是这个类,而不会变成函数或方法
print('class_instance type {type} '.format(type=type(the_class)))
# class_instance type <class_ '__main__.TheClass'>

关于Python的函数(Method)与方法(Function)的更多相关文章

  1. python enumerate() 函数的使用方法

    列表是最常用的Python数据类型,前段时间看书的时候,发现了enumerate() 函数非常实用,因为才知道下标可以这么容易的使用,总结一下. class enumerate(object): &q ...

  2. python spilt()函数的使用方法

    Python中的split()函数的用法 Python中有split()和os.path.split()两个函数,具体作用如下:split():拆分字符串.通过指定分隔符对字符串进行切片,并返回分割后 ...

  3. python第十九天 关于方法,函数

    1.先从简单的函数说起 from inspect import isfunction 导入判断是否是function def foo():pass 定义了一个函数 print(foo) <fun ...

  4. Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究

    Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究 一丶反射 什么是反射: ​ 反射的概念是由Smith在1982年首次提出的 ...

  5. python中函数和方法区别,以及如何给python类动态绑定方法和属性(涉及types.MethodType()和__slots__)

    网上有很多同义但不同方式的说法,下面的这个说法比较让你容易理解和接受 与类和实例无绑定关系的function都属于函数(function): 与类和实例有绑定关系的function都属于方法(meth ...

  6. Python的程序结构[1] -> 方法/Method[2] -> 魔术方法 __init__ / __del__ / __new__

    魔术方法 / Magic Method 魔法方法就是可以给你的类增加魔力的特殊方法(实质应称为特殊方法,魔术方法在JavaScript中有所体现,对象具有不透明特性,而且无法在自定义对象中模拟这些行为 ...

  7. python isinstance和issubclass,区分方法和函数,反射

    一.isinstance和issubclass 1.isinstance class Animal: def eat(self): print('刚睡醒吃点儿东西') class Cat(Animal ...

  8. 【C++实现python字符串函数库】strip、lstrip、rstrip方法

    [C++实现python字符串函数库]strip.lstrip.rstrip方法 这三个方法用于删除字符串首尾处指定的字符,默认删除空白符(包括'\n', '\r', '\t', ' '). s.st ...

  9. 举例详解Python中的split()函数的使用方法

    这篇文章主要介绍了举例详解Python中的split()函数的使用方法,split()函数的使用是Python学习当中的基础知识,通常用于将字符串切片并转换为列表,需要的朋友可以参考下   函数:sp ...

随机推荐

  1. 【WF2017】Mission Improbable

    http://www.lydsy.com/JudgeOnline/problem.php?id=4950 对于俯视图很好解决,把所有不是0的位置拿到剩1就可以了. 对于正视图与侧视图,稍微想一下也能发 ...

  2. PHP递归解决兔子问题,面试必备

    接到面试通知辗转反侧,一直在默念明天改如何介绍自己的项目经验等.早早的起床,洗漱,把自己的总结的问题自问自答了一些.匆匆吃了早饭,挤进让人面目狰狞的地铁,此时什么都不顾,只盼着赶紧下地铁.终于提前半小 ...

  3. 微服务架构之RPC-client序列化细节

    通过上篇文章的介绍,知道了要实施微服务,首先要搞定RPC框架,RPC框架的职责要向[调用方]和[服务提供方]屏蔽各种复杂性: (1)让调用方感觉就像调用本地函数一样 (2)让服务提供方感觉就像实现一个 ...

  4. sqlser 2005 对称加密,非对称加密笔记

    一:对称加密  原始明文---密钥---加密数据---密钥---原始明文 速度快,通过算法将明文混淆,占用系统资源少 二:非对称加密 加密解密速度慢,较高的系统资源占用 三:混合数据加密 加密过程:随 ...

  5. [转载]ArchLinux 添加 archlinuxcn 源 密钥错误

    http://www.jianshu.com/p/8ed688b0a096 杜龙少 正在检查密钥环里的密钥 [######################] 100% 正在下载所需的密钥...... ...

  6. 《计算机程序的构造和解释(第2版)》【PDF】下载

    <计算机程序的构造和解释(第2版)>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382255 内容简介 <计算机程序的构造 ...

  7. 插入光盘,创建挂载点,挂载设备,安装rpm包,升级rpm包,卸载rpm包,查询rpm包是否安装,查询rpm包信息、安装位置,查询系统文件名属于哪个安装包

    插入光盘: 创建挂载点: 创建挂载点. 挂载设备:或者mount /dev/sr0 /mnt/cdrom 安装rpm包: [root@localhost Packages]# rpm -ivh mys ...

  8. 那些容易遗忘的web前端问题

    背景: 年底将至,本人这只才出门的前端菜鸟,终于有空闲的时间来整理一下最近投简历时出现的问题.有的是经常使用但是没有仔细留意造成的:有的是个人认为根本没人使用而忽略的.为了下次不出现这种错误,进行一下 ...

  9. Visual Studio Code 快捷键大全(Windows)

    Visual Studio Code 是一款优秀的编辑器,非常适合编写 TS 以及 React .最近在学习 AngularJs 2,开始使用 VSCode,特意整理翻译了一下官网的快捷键.因为已经习 ...

  10. 解决报错:IncompleteElementException: Could not find result map...

    今天遇到这样一个报错,记录一下: org.apache.ibatis.builder.IncompleteElementException: Could not find result map com ...