实例方法

在类中定义的方法默认都是实例方法,前面几篇文章已经大量使用到实例方法

实例方法栗子

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

最新文章

  1. hypermesh2flac3d
  2. Linux下MakeFile初探
  3. Quality trimming using Trimmomatic
  4. JS 获取当前浏览器类型
  5. UNITY_MATRIX_IT_MV[Matrix] (转载)
  6. UVa 129 (回溯法) Krypton Factor
  7. Java中WebService实例
  8. php 汉字转拼音 [包含20902个基本汉字+5059生僻字]
  9. 前端复制功能的若干 -- document.execCommand()
  10. 微信开发(2)---微信小程序开发实战part1
  11. 02-windows 安装以太坊 ethereum 客户端 (win7-64)-大叔思维
  12. [转载] ConcurrentHashMap原理分析
  13. [LeetCode] Construct String from Binary Tree 根据二叉树创建字符串
  14. 一个maven项目打多个可执行Jar文件
  15. Goroutine陷阱
  16. java 乱码问题集
  17. visual studio code前端插件及常用快捷键【转】
  18. 动态加载DataGrid表头及数据
  19. linux定时器【转】
  20. js json转url参数

热门文章

  1. C语言变量为何先定义后使用
  2. Dubbo的优雅下线原理分析
  3. Jmeter入门 浏览器设置代理服务器和录制脚本
  4. GetOverlappedResult 函数
  5. dhanush
  6. 大数据学习(03)——HDFS的高可用
  7. Python - 解包的各种骚操作
  8. Hive之分析函数
  9. [JS]异步任务之事件循环
  10. OpenGL学习笔记(二)画三角形