Python中的属性和实例方法、类方法、静态方法的用法和区别

2024-05-25 23:18

本文主要是介绍Python中的属性和实例方法、类方法、静态方法的用法和区别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

类属性、实例属性

类属性

  • 定义:类属性是直接在类中定义的属性。
  • 类属性可以通过类或类的实例访问到。
  • 类属性只能通过类对象来修改,无法通过实例对象修改。
class A(Object):count = 0a = A()
a.count = 10
print('A, ', A.count)
print('a, ', a.count)

A, 0
a, 10

A.count = 100
print('A, ', A.count)
print('a, ', a.count)

A, 100
a, 100

实例属性

  • 通过实例对象添加的属性属于实例属性
  • 实例属性只能通过实例对象来访问和修改,类对象无法访问
class A():count = 0def __init__(self):self.name = 'stone'  # 实例属性# print('A, ', A.name)   # 报错----类对象无法访问实例属性
print('a, ', a.name)

注意:

  • 如果是公共的,所有实例都共享这个属性则使用类属性;
  • 只有当前对象(实例)使用则使用实例属性;

实例方法、类方法、静态方法的用法和区别

本章节转自:https://blog.csdn.net/lihao21/article/details/79762681
Python 实例方法、类方法和静态方法

在 Python 中,实例方法(instance method),类方法(class method)与静态方法(static method)经常容易混淆。本文通过代码例子来说明它们的区别。

实例方法

Python 的实例方法用得最多,也最常见。我们先来看 Python 的实例方法。

class Kls(object):def __init__(self, data):self.data = datadef printd(self):print(self.data)# 实例调用,自动将当前调用对象作为self传入
ik1.printd()
ik2.printd()# 类调用,不会自动传入self,必须手动传入self
Kls.printd(ik1)
Kls.printd(ik2)

输出:

leo
lee
leo
lee

上述例子中,printd为一个实例方法。

实例方法第一个参数为self

当使用ik1.printd()调用实例方法时,实例ik1会传递给self参数,这样self参数就可以引用当前正在调用的实例方法的实例。利用实例方法的这个特性,上述代码正确输出了两个实例的成员数据。

实例方法可以通过实例和类进行调用

  • 通过实例调用时,会自动将当前调用对象作为self传入;
  • 通过类调用时,不会自动传入self,必须手动传入self;

类方法

Python 的类方法采用装饰器@classmethod来定义,我们直接看例子。

class Kls(object):num_inst = 0def __init__(self):Kls.num_inst = Kls.num_inst + 1@classmethoddef get_no_of_instance(cls):print("这是一个类方法", cls)return cls.num_instik1 = Kls()
ik2 = Kls()print(ik1.get_no_of_instance())
print(Kls.get_no_of_instance())

输出:

这是一个类方法 <class '__main__.Kls'>
2
这是一个类方法 <class '__main__.Kls'>
2

在上述例子中,我们需要统计类Kls实例的个数,因此定义了一个类变量num_inst来存放实例个数。通过装饰器@classmethod的使用,方法get_no_of_instance被定义成一个类方法。在调用类方法时,Python 会将类(class Kls)传递给cls,这样在get_no_of_instance内部就可以引用类变量num_inst

类方法第一个参数为cls,会被自动传入,cls就是当前的类对象


由于在调用类方法时,只需要将类型本身传递给类方法,因此,

类方法既可以通过类调用,也可以通过实例来调用,两者没有区别。

静态方法

在开发中,我们常常需要定义一些方法,这些方法跟类有关,

但在实现时并不需要引用类或者实例。

例如,设置环境变量,修改另一个类的变量,等。这个时候,我们可以使用静态方法。

静态方法,基本上是一个和当前类无关的方法,它只是一个保存到当前类中的函数。

静态方法一般都是工具方法,和当前类无关。


Python 使用装饰器@staticmethod来定义一个静态方法。

IND = 'ON'class Kls(object):def __init__(self, data):self.data = data@staticmethoddef checkind():return IND == 'ON'def do_reset(self):if self.checkind():print('Reset done for: %s' % self.data)def set_db(self):if self.checkind():print('DB connection made for: %s' % self.data)ik1 = Kls(24)
ik1.do_reset()
ik1.set_db()

输出:

Reset done for: 24
DB connection made for: 24

在代码中,我们定义了一个全局变量IND,由于IND跟类Kls相关,所以我们将方法checkind放置在类Kls中定义。方法checkind只需检查IND的值,而不需要引用类或者实例,因此,我们将方法checkind定义为静态方法。
对于静态方法,Python 并不需要传递类或者实例,因此,

静态方法既可以使用类调用,也可以使用实例来调用。

实例方法,类方法与静态方法的区别

我们用代码说明实例方法,类方法,静态方法的区别。注意下述代码中方法fooclass_foostatic_foo的定义以及使用。

class Kls(object):def foo(self, x):print('executing foo(%s,%s)' % (self, x))@classmethoddef class_foo(cls,x):print('executing class_foo(%s,%s)' % (cls,x))@staticmethoddef static_foo(x):print('executing static_foo(%s)' % x)ik = Kls()# 实例方法
ik.foo(1)
print(ik.foo)
print('==========================================')# 类方法
ik.class_foo(1)
Kls.class_foo(1)
print(ik.class_foo)
print('==========================================')# 静态方法
ik.static_foo(1)
Kls.static_foo('hi')
print(ik.static_foo)

输出:

executing foo(<__main__.Kls object at 0x0551E190>,1)
<bound method Kls.foo of <__main__.Kls object at 0x0551E190>>
==========================================
executing class_foo(<class '__main__.Kls'>,1)
executing class_foo(<class '__main__.Kls'>,1)
<bound method type.class_foo of <class '__main__.Kls'>>
==========================================
executing static_foo(1)
executing static_foo(hi)
<function static_foo at 0x055238B0>

(1)对于实例方法,调用时会把实例ik作为第一个参数传递给self参数。因此,调用ik.foo(1)时输出了实例ik的地址。

(2)对于类方法,调用时会把类Kls作为第一个参数传递给cls参数。因此,调用ik.class_foo(1)时输出了Kls类型信息。
前面提到,可以通过类也可以通过实例来调用类方法,在上述代码中,我们再一次进行了验证。

(3)对于静态方法,调用时并不需要传递类或者实例。

其实,静态方法很像我们在类外定义的函数,只不过静态方法可以通过类或者实例来调用而已。

值得注意的是,在上述例子中,

1、foo只是个函数,但当调用ik.foo的时候我们得到的是一个已经跟实例ik绑定的函数。调用foo时需要两个参数,但调用ik.foo时只需要一个参数。fooik进行了绑定,因此,当我们打印ik.foo时,会看到以下输出:

<bound method Kls.foo of <__main__.Kls object at 0x0551E190>>

2、当调用ik.class_foo时,由于class_foo是类方法,因此,class_fooKls进行了绑定(而不是跟ik绑定)。当我们打印ik.class_foo时,输出:

<bound method type.class_foo of <class '__main__.Kls'>>

3、当调用ik.static_foo时,

静态方法并不会与类或者实例绑定

因此,打印ik.static_foo(或者Kls.static_foo)时输出:

<function static_foo at 0x055238B0>

概括来说,是否与类或者实例进行绑定,这就是实例方法,类方法,静态方法的区别。

参考资料

  1. https://www.pythoncentral.io/difference-between-staticmethod-and-classmethod-in-python/
  2. https://taizilongxu.gitbooks.io/stackoverflow-about-python/content/14/README.html
  3. https://kuanghy.github.io/2015/12/19/python-variable
  4. https://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod-in-python

这篇关于Python中的属性和实例方法、类方法、静态方法的用法和区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1002890

相关文章

PHP轻松处理千万行数据的方法详解

《PHP轻松处理千万行数据的方法详解》说到处理大数据集,PHP通常不是第一个想到的语言,但如果你曾经需要处理数百万行数据而不让服务器崩溃或内存耗尽,你就会知道PHP用对了工具有多强大,下面小编就... 目录问题的本质php 中的数据流处理:为什么必不可少生成器:内存高效的迭代方式流量控制:避免系统过载一次性

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

Python正则表达式匹配和替换的操作指南

《Python正则表达式匹配和替换的操作指南》正则表达式是处理文本的强大工具,Python通过re模块提供了完整的正则表达式功能,本文将通过代码示例详细介绍Python中的正则匹配和替换操作,需要的朋... 目录基础语法导入re模块基本元字符常用匹配方法1. re.match() - 从字符串开头匹配2.

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

通过Docker容器部署Python环境的全流程

《通过Docker容器部署Python环境的全流程》在现代化开发流程中,Docker因其轻量化、环境隔离和跨平台一致性的特性,已成为部署Python应用的标准工具,本文将详细演示如何通过Docker容... 目录引言一、docker与python的协同优势二、核心步骤详解三、进阶配置技巧四、生产环境最佳实践

Python一次性将指定版本所有包上传PyPI镜像解决方案

《Python一次性将指定版本所有包上传PyPI镜像解决方案》本文主要介绍了一个安全、完整、可离线部署的解决方案,用于一次性准备指定Python版本的所有包,然后导出到内网环境,感兴趣的小伙伴可以跟随... 目录为什么需要这个方案完整解决方案1. 项目目录结构2. 创建智能下载脚本3. 创建包清单生成脚本4

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

python获取指定名字的程序的文件路径的两种方法

《python获取指定名字的程序的文件路径的两种方法》本文主要介绍了python获取指定名字的程序的文件路径的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 最近在做项目,需要用到给定一个程序名字就可以自动获取到这个程序在Windows系统下的绝对路径,以下

Vue和React受控组件的区别小结

《Vue和React受控组件的区别小结》本文主要介绍了Vue和React受控组件的区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录背景React 的实现vue3 的实现写法一:直接修改事件参数写法二:通过ref引用 DOMVu