Python - 面向对象编程 - 实例方法、静态方法、类方法
实例方法
在类中定义的方法默认都是实例方法,前面几篇文章已经大量使用到实例方法
实例方法栗子
class PoloBlog:
def __init__(self, name, age):
print("自动调用构造方法")
self.name = name
self.age = age def test(self):
print("一个实例方法,需要通过对象调用")
print("my name is :", self.name, " and my age is :", self.age) blog = PoloBlog("小菠萝", 24)
blog.test() # 输出结果
自动调用构造方法
一个实例方法,需要通过对象调用
my name is : 小菠萝 and my age is : 24
- 最少也要包含一个 self 参数,用于绑定调用此方法的实例对象(Python 会自动完成绑定)
- 实例方法通常会用实例对象直接调用
通过类名调用实例方法
Python 也支持通过类名调用实例方法,但需要手动给 self 参数传实例对象
blog = PoloBlog("小菠萝", 24)
PoloBlog.test(blog)
# 输出结果
自动调用构造方法
一个实例方法,需要通过对象调用
my name is : 小菠萝 and my age is : 24
假设不传实例对象,pycharm 会有warning

类方法
类方法和实例方法很相似,又很不相似
相似点
- 也至少要包含一个参数,不过通常命名为 cls
- 在调用类方法时,无需显式为 cls 参数传参,但传递的并不是实例对象,而是类对象本身
不同点
最大的不同在于需要使用 @classmethod 装饰器才能称为类方法
实际栗子
class PoloBlog:
# 类属性
sum = 0 # 类方法, 添加装饰器
@classmethod
def class_func(cls):
print("class_func cls 对象的 id ", id(cls))
cls.sum += 1
print("类属性 sum ", cls.sum) @classmethod
def class_func_twi(cls):
print("class_func_twi cls 对象的 id ", id(cls))
cls.sum += 1
print("类属性 sum ", cls.sum) PoloBlog.class_func()
PoloBlog.class_func_twi() # 输出结果
class_func cls 对象的 id 140583542774880
类属性 sum 1
class_func_twi cls 对象的 id 140583542774880
类属性 sum 2
cls 代表的是同一个对象,类对象
类方法可以调用实例方法吗?
可以,但有局限性
class PoloBlog:
# 类属性
sum = 0 def __init__(self, sum):
self.sum = sum # 实例方法
def test(self):
print("self id is ",id(self))
print("self 对象的 sum 属性值为:", self.sum) # 类方法, 添加装饰器
@classmethod
def class_func(cls):
print("cls id is ", id(cls))
print("类属性 sum ", cls.sum)
# 调用实例方法
cls.test(cls) PoloBlog.class_func() # 输出结果
cls id is 140500501817184
类属性 sum 0
self id is 140500501817184
self 对象的 sum 属性值为: 0
- 类方法调用实例方法的方式: cls.实例方法(cls) ,通过 cls 调用,且还要传递 cls 为参数
- 从 id 相同即可看出,实例方法接收的仍然是一个类对象
实例对象可以调用类方法吗?
可以,但不建议
blog = PoloBlog(2)
blog.class_func() # 输出结果
cls id is 140500501817184
类属性 sum 0
self id is 140500501817184
self 对象的 sum 属性值为: 0
- blog 是一个实例对象,且初始化赋值了 sum 实例属性
- 但最后实例方法打印的仍然是 sum 类属性,表明类方法无法访问实例属性
- 且 cls、self 参数的 id 和上面的栗子完全一样,表明即使通过实例对象调用类方法,传递的仍然是类对象的引用,所有类方法都被同一个类对象调用,一个类只有一个类对象
实例方法可以调用类属性吗?
可以,但不能通过实例对象调用,只能通过类对象
class PoloBlog:
# 类属性
name = "类啊类属性" def __init__(self, name):
self.name = name # 实例方法
def test(self):
# 错误栗子
# print(name) # 访问的仍然是实例属性
print(self.name) # 通过类名访问
print(PoloBlog.name) blog = PoloBlog("小菠萝")
blog.test() # 输出结果
小菠萝
类啊类属性
假设直接调用 name 变量可以吗
肯定不行,报错

扩展思考题!
- 一个方法内部既需要访问实例属性,又需要访问类属性,应该定义为什么方法?
- 答案:实例方法,因为可以通过 类对象.类属性 来访问,但在类方法中无法访问实例属性
代码栗子直接看上面一个就是啦!
静态方法
- 和之前学过的函数一毛一样,唯一区别是:静态方法需要定义在类体中,且需要添加 @staticmethod 装饰器
- 静态方法没有 self、cls 参数,也不需要至少传一个参数,和普通函数一样
- Python 解释器不会对它包含的参数做任何类或对象的绑定,所以静态方法无法调用任何类属性、类方法、实例属性、实例方法,除非通过类名和实例对象
class PoloBlog:
# 静态方法
@staticmethod
def info(name, age):
print(name, age)
# 通过类对象调用
PoloBlog.info("小菠萝111", 24)
blog = PoloBlog()
# 通过实例对象调用
blog.info("小菠萝222", 14)
# 输出结果
小菠萝111 24
小菠萝222 14
关于 classmethod 和 staticmethod 的实际应用场景
可以参考这篇文章
待我实战后再来完善此章节
https://www.zhihu.com/question/20021164
Python - 面向对象编程 - 实例方法、静态方法、类方法的更多相关文章
- python类的实例方法\静态方法\类方法区别解析(附代码)
前言 搞了好久python,一直搞得不太清楚这几种类的方法,今天花时间好好测试一下,算是弄懂点皮毛吧. 三种方法的不同 先剽窃个图看一下 可以看到,实例是三种方法都可以调用的,而类只可以调用两种.所以 ...
- python 面向对象编程(一)
一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法. 类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义: class c ...
- Python 面向对象编程基础
Python 面向对象编程基础 虽然Pthon是解释性语言,但是Pthon可以进行面向对象开发,小到 脚本程序,大到3D游戏,Python都可以做到. 一类: 语法: class 类名: 类属性,方法 ...
- python面向对象编程进阶
python面向对象编程进阶 一.isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 1 ...
- 图解python | 面向对象编程
作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/56 本文地址:http://www.showmeai.tech/article-det ...
- python 面向对象编程学习
1. 问题:将所有代码放入一个py文件:无法维护 方案:如果将代码才分放到多个py文件,好处: 1. 同一个名字的变量互相不影响 2.易于维护 3.引用模块: import module 2.包:解决 ...
- Python面向对象编程指南
Python面向对象编程指南(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1SbD4gum4yGcUruH9icTPCQ 提取码:fzk5 复制这段内容后打开百度网 ...
- Python面向对象编程(下)
本文主要通过几个实例介绍Python面向对象编程中的封装.继承.多态三大特性. 封装性 我们还是继续来看下上文中的例子,使用Student类创建一个对象,并修改对象的属性.代码如下: #-*- cod ...
- Python 面向对象编程——访问限制
<无访问限制的对象> 在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑.但是,从前面Student类的定义来看(见:Py ...
随机推荐
- grub2引导各种ISO系统镜像
1 grub2引导winpe 1下载winpe.iso镜像,放置在U盘的根目录下 2下载syslinux的memdisk,放置在U盘的根目录下 3 set root=(hd0,msdos1) 设置U ...
- Android Studio(或IntelliJ IDEA )把Android程序运行到由VirtualBox创建 Android x86虚拟机中
一.运行前相关配置 1.把Android sdk platform-tools目录下的adb程序加入到path环境变量,默认情况下是其路径是: C:/Users/ [User]/AppData/Loc ...
- tomcat与springmvc 结合 之---第19篇(下,补充) springmvc 加载.xml文件的bean标签的过程
writedby 张艳涛,上一篇写了springmvc对<mvc:annoXXXX/>标签的解析过程,其实是遗漏重要的细节,因为理解的不深入吧 今天接着解析<bean>标签 & ...
- jvm源码解读--16 cas 用法解析
CAS的意思是campare and sweep比较交换 这个如果不用代码会比较抽象,那么在源码中进行解释 void ATTR ObjectMonitor::enter(TRAPS) { // The ...
- element UI rules prop对应关系
- 大数据学习(14)—— HBase进阶
HBase读写流程 在网上找了一张图,这个画的比较简单,就拿这个图来说吧. 写流程 1.当Client发起一个Put请求时,首先访问Zookeeper获取hbase:meta表. 2.从hbase:m ...
- Sql Server备份表,动态生成表名称
1.常用的数据库备份表语句 SELECT * INTO tableNameNew FROM tableName 2.动态备份表,且备份表名称后面增加三位随机字符和当前日期 1 DECLARE @bak ...
- AT指令集及其通信测试方式
1 前言 AT即Attention,AT指令集是从终端设备(Terminal Equipment,TE)向终端适配器(Terminal Adapter, TA)发送的.通过TA,TE发送AT指令来控制 ...
- NCB | 定量蛋白质组学揭示细胞外泌体通用标志物Syntenin-1
外泌体 (exosomes) 是由哺乳动物细胞通过"内吞-融合-外排"等机制,主动向胞外释放的纳米级 (直径40~60 nm) 双层囊泡小体,携带蛋白质.核酸.脂质等多种生物活性分 ...
- Java ParallelStream
ParallelStream 处理数据 Stream 接口提供了parallelStream方法来将集合转换为并行流.即将一个集合分为多个数据块,并用不同的线程分别处理每个数据块的流. 并且使用par ...