首页 > 编程语言 >Python成员方法、类方法与静态方法的区别

Python成员方法、类方法与静态方法的区别

时间:2023-09-18 21:15:08浏览次数:29  
标签:调用 静态方法 Python 实例 MyClass 方法

Python基础教程:3个方面理解Python的类方法与静态方法

在Python语言中有如下3种方法:

  • 成员方法
  • 类方法(classmethod)
  • 静态方法(staticmethod)

可能很多同学不清楚这3种方法,尤其是后两类方法到底有什么不同。为此,本文将对这3种方法做一次敲骨沥髓的深度剖析。

先说一下这3种方法的差异,了解差异后,就自然了解他们的区别了。

这3种方法有如下3点差异:

  • 方法定义
  • 调用方式
  • 方法归属

1. 方法定义

这3种方法在定义上有如下2点不同。

(1)是否使用装饰器

成员方法不需要使用任何装饰器,直接使用def关键字定义方法即可,代码如下:

类方法必须使用@classmethod装饰器修饰,代码如下:

静态方法必须使用@staticmethod装饰器修饰,代码如下:

(2)参数不同

成员方法与类方法,除正常的方法参数外,都必须多加一个参数,这个参数必须是方法的第1个参数。参数可以是任意名,但通常成员方法的第1个参数名是self,类方法的第1个参数名是cls。而静态方法不需要加额外的参数。见前面代码中的method方法。

self和cls分别表示类实例和类本身,这一点在后面会详细介绍。

下面看一个完整定义这3种方法的代码:

2. 调用方式

(1)调用成员方法

成员方法只能通过类实例调用,代码如下:

在定义成员方法时,第一个参数是表示类实例的self,这个参数并不需要在调用时显式指定,而是由Python运行时自动处理。对于上面的调用代码,Python运行时会自动将表示MyClass实例的my传入foo方法。所以my就是foo方法中第一个参数self的值。通过self,在方法内部可以引用MyClass实例的其他成员。

执行这段代码,会输出如下内容。很明显,self是一个对象,首地址是0x7f7f1003df70

(2)调用类方法

类方法可以通过类实例调用,也可以直接通过类本身调用,代码如下:

执行这段代码,会输出如下内容:

很明显,class_foo方法的cls参数不再是类的实例(因为没有对象地址),而是MyClass类本身。所以不管使用哪一种方式调用类方法,传入class_foo方法第1个参数的值都是类本身。所以通过类方法,可以获取类的静态资源,与直接引用MyClass是一样的。

(3)调用静态方法

调用静态方法与调用类方法一样,都可以通过类实例或类本身调用,从这一点看不出来哪一个是类方法,哪一个是静态方法,代码如下:

执行这段代码,会输出如下内容:

由于在定义静态方法时并没有指定任何额外的参数,所以静态方法并没有与类或类实例绑定,当然,在静态方法中,仍然可以通过MyClass引用类中的静态成员。

3. 方法归属

方法归属是这3种方法的重要区别,可以分别将这3种方法作为属性输出,看看是什么结果。

执行这段代码,会输出如下内容:

从输出结果可以看到,成员方法绑定到了类实例中(该方法属于类实例),类方法与类本身绑定,而静态方法就是一个独立的对象(因为有对象首地址),不属于任何类或实例。
从以上3个方法我们已经可以得出classmethod方法与staticmethod的区别,下面总结一下:

4. 总结

(1)共同点
classmethod方法与staticmethod方法的共同点只有一个,就是调用时,既可以使用类实例,也可以直接用类本身调用。所以从调用上,根本分不出是类方法,还是静态方法。
(2)差异
类方法顾名思义,是与类绑定的,相当于下面的调用方式:

只是类方法在调用时自动传入了MyClass,而上面的代码是显式传入MyClass的,但最终效果是完全一样的。

而静态方法其实就是一个寄居蟹,完全不属于它的宿主。只是寄居在类中。换句话说,直接将静态方法从类中移出来作为独立的函数,完全不需要修改一行代码就可以直接运行。因为静态方法不会访问类中的任何成员,当然,可能访问类的静态成员,但也是使用类本身(如MyClass),这种访问方式,独立的函数同样可以。

其实Python提供静态方法倒不是非常必要,不过Java就很有必要了。由于Python支持独立的函数形式,所以不使用静态方法,也可以使用独立的函数。通常独立的函数可以全局访问(在一个模块访问另外一个模块中的函数)。而Java是纯面向对象语言,并不支持独立函数。所以为了实现这种全局调用的效果,Java类提供了静态方法,可以通过MyClass.process(…)的形式在其他类访问MyClass中的process方法。

不过Python中的静态方法到是有一个作用,就是分组。如果模块中有大量的独立函数,而且这些独立函数的功能可能完全不同,就显得比较乱,所以通常的做法是将这些独立函数作为Python类的静态方法,将同一类型的独立函数放到一个类中,这样就会让整个代码结构显得更有调理。就像将文件存放在硬盘上一样,如果将所有的文件都放在一个目录中,找文件会很费劲。所以需要将同一类文件放到特定的目录中,这样看起来目录结构更清晰。所以静态方法与Python类,就相当于文件与目录的关系,主要就是起到分类的作用。

(3)使用场景

如果只是描述类的一般的动作,而且类的不同实例,动作的表现可能还不同,那么就用成员方法,例如,move(移动)、fly(飞)、getAge(如不同Person类的实例,可能年龄是不同的)等。
类方法与静态方法大多数时候可以互换,但如果想让方法保持独立,应该使用静态方法,因为静态方法不需要多余的参数接收类或类实例。

标签:调用,静态方法,Python,实例,MyClass,方法
From: https://www.cnblogs.com/wyl-520/p/17713043.html

相关文章

  • [HUBUCTF 2022 新生赛]ezPython
    附件链接:https://wwvc.lanzouj.com/iIqq218z5x0d给了一个pyc文件利用命令将pyc转换为py文件uncompyle6ezPython.pyc>ezPython.py打开py文件#uncompyle6version3.9.0#Pythonbytecodeversionbase3.7.0(3394)#Decompiledfrom:Python3.8.2(tags/v3.8.2:7b3ab......
  • python学习计划
    首先我要去购买《Python编程,从入门到实践》这本书来学习python这门课程首先第一个月我要学习python的基础知识第一周:了解Python的基础,包括变量、数据类型、运算符和基本输入/输出。第二周:学习条件语句(if、elif、else)和循环(for、while)。第三周:掌握Python的函数和参数传递。第......
  • hmac:Python密码消息签名
    前言HMAC算法可以用于验证信息的完整性,这些信息可能在应用之间传递,或者存储在一个可能有安全威胁的地方。其基本思路:生成实际数据的一个密码散列,并提供一个共享的秘密密钥。然后使用得到的散列检查所传输或存储的信息,以确定一个信任级别,而不传输秘密密钥。消息签名hmac库提供......
  • Python中数据类转换为JSON的方法
    dataclass到Python中的JSONJavaScriptObjectNotation或JSON表示使用编程语言中的文本组成的脚本(可执行)文件来存储和传输数据。Python通过JSON内置模块支持JSON。因此,我们在Python脚本中导入JSON包,以利用这一能力。JSON中使用的引号字符串包含了键值映射中的值。它与Pytho......
  • Python教程:@符号的用法
    @符号在Python中最常见的使用情况是在装饰器中。一个装饰器可以让你改变一个函数或类的行为。@符号也可以作为一个数学运算符使用,因为它可以在Python中乘以矩阵。本教程将教你如何使用Python的@符号。装饰器中使用@符号装饰器是一个接受一个函数作为参数的函数,向其添加......
  • Python中装饰器的顺序
    什么是装饰器,它们如何被使用,以及我们如何利用它们来构建代码。我们将看到装饰器是如何成为一个强大的工具,可以用来为我们的应用程序添加功能,并且可以在Python编程语言中找到。装饰器顺序在Python中,装饰器是一个特殊的函数,可以修改另一个函数的行为。装饰器是一种设计模式,它在不......
  • Python学习笔记
    Python语言是一种解释性、面向对象、动态数据类型的高级程序设计语言创始人:吉多,荷兰人时间:1989编写的,1991公开发行Python语言特点开源、免费面向过程、面向对象、交互式编程面向过程:以事情或解决问题的过程为中心,主要考虑解决问题的思路和步骤面向对象:以事务为中心,主要考虑解决问......
  • Python(二)
    字典字典属于无序、可变的数据类型以键:值的方式存储、通过键来访问字典的值说明:字典以花括号{}括起来的数据集合,不同数据间以“,”分隔,每个数据以“键:值”的形式表达语法格式:#创建字典字典名={键1:值1,键2:值2,键3:值3,键4:值4,…}#常用字典名=dict(键1=值1,键2......
  • Go比Python快多少倍?请看一个简单的例子
    需求两个0-10000的数组,循环遍历两个数组,获取两个元素,打印出乘积为56213的所有元素Python实现importdatetimes=datetime.datetime.now()foriinrange(10000):forjinrange(10000):ifi*j==56213:print(f"{i}*{......
  • 2022年07月 python界面可视化 VS2022配置PyQt5环境
    文章目录 一、VS2022配置PyQt5环境1.安装anaconda及opencv-python1.1安装对应的anaconda包1.2安装opencv-python2.安装PyQt53.安装PyQt常用工具4.配置系统环境变量5.配置VS2022中的外部工具6.第一个VS2022下的pyqt5程序一、VS2022配置PyQt5环境本机环境:......