Python - 面向对象编程 - 实例方法、静态方法、类方法

简介: 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

image.png

类方法


类方法和实例方法很相似,又很不相似

 

相似点

  • 也至少要包含一个参数,不过通常命名为 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 变量可以吗

肯定不行,报错

image.png

扩展思考题!

  • 一个方法内部既需要访问实例属性,又需要访问类属性,应该定义为什么方法?
  • 答案:实例方法,因为可以通过 类对象.类属性 来访问,但在类方法中无法访问实例属性

代码栗子直接看上面一个就是啦!

 

静态方法


  • 和之前学过的函数一毛一样,唯一区别是:静态方法需要定义在类体中,且需要添加 @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

相关文章
|
11天前
|
JSON 数据可视化 API
Python 中调用 DeepSeek-R1 API的方法介绍,图文教程
本教程详细介绍了如何使用 Python 调用 DeepSeek 的 R1 大模型 API,适合编程新手。首先登录 DeepSeek 控制台获取 API Key,安装 Python 和 requests 库后,编写基础调用代码并运行。文末包含常见问题解答和更简单的可视化调用方法,建议收藏备用。 原文链接:[如何使用 Python 调用 DeepSeek-R1 API?](https://apifox.com/apiskills/how-to-call-the-deepseek-r1-api-using-python/)
|
28天前
|
测试技术 Python
【03】做一个精美的打飞机小游戏,规划游戏项目目录-分门别类所有的资源-库-类-逻辑-打包为可玩的exe-练习python打包为可执行exe-优雅草卓伊凡-持续更新-分享源代码和游戏包供游玩-1.0.2版本
【03】做一个精美的打飞机小游戏,规划游戏项目目录-分门别类所有的资源-库-类-逻辑-打包为可玩的exe-练习python打包为可执行exe-优雅草卓伊凡-持续更新-分享源代码和游戏包供游玩-1.0.2版本
106 31
【03】做一个精美的打飞机小游戏,规划游戏项目目录-分门别类所有的资源-库-类-逻辑-打包为可玩的exe-练习python打包为可执行exe-优雅草卓伊凡-持续更新-分享源代码和游戏包供游玩-1.0.2版本
|
28天前
|
人工智能 自然语言处理 算法
随机的暴力美学蒙特卡洛方法 | python小知识
蒙特卡洛方法是一种基于随机采样的计算算法,广泛应用于物理学、金融、工程等领域。它通过重复随机采样来解决复杂问题,尤其适用于难以用解析方法求解的情况。该方法起源于二战期间的曼哈顿计划,由斯坦尼斯拉夫·乌拉姆等人提出。核心思想是通过大量随机样本来近似真实结果,如估算π值的经典示例。蒙特卡洛树搜索(MCTS)是其高级应用,常用于游戏AI和决策优化。Python中可通过简单代码实现蒙特卡洛方法,展示其在文本生成等领域的潜力。随着计算能力提升,蒙特卡洛方法的应用范围不断扩大,成为处理不确定性和复杂系统的重要工具。
69 21
|
26天前
|
数据挖掘 数据处理 开发者
Python3 自定义排序详解:方法与示例
Python的排序功能强大且灵活,主要通过`sorted()`函数和列表的`sort()`方法实现。两者均支持`key`参数自定义排序规则。本文详细介绍了基础排序、按字符串长度或元组元素排序、降序排序、多条件排序及使用`lambda`表达式和`functools.cmp_to_key`进行复杂排序。通过示例展示了如何对简单数据类型、字典、类对象及复杂数据结构(如列车信息)进行排序。掌握这些技巧可以显著提升数据处理能力,为编程提供更强大的支持。
32 10
|
2月前
|
安全
Python-打印99乘法表的两种方法
本文详细介绍了两种实现99乘法表的方法:使用`while`循环和`for`循环。每种方法都包括了步骤解析、代码演示及优缺点分析。文章旨在帮助编程初学者理解和掌握循环结构的应用,内容通俗易懂,适合编程新手阅读。博主表示欢迎读者反馈,共同进步。
|
2月前
|
数据采集 存储 XML
python实战——使用代理IP批量获取手机类电商数据
本文介绍了如何使用代理IP批量获取华为荣耀Magic7 Pro手机在电商网站的商品数据,包括名称、价格、销量和用户评价等。通过Python实现自动化采集,并存储到本地文件中。使用青果网络的代理IP服务,可以提高数据采集的安全性和效率,确保数据的多样性和准确性。文中详细描述了准备工作、API鉴权、代理授权及获取接口的过程,并提供了代码示例,帮助读者快速上手。手机数据来源为京东(item.jd.com),代理IP资源来自青果网络(qg.net)。
跟我从0学Python——类的继承和多态
类的继承和多态 —— 面向对象编程的扩展与灵活性
|
9月前
|
搜索推荐 Python
Python学习 -- 类的继承
Python学习 -- 类的继承
62 0
|
Kotlin Python
Python(三十一)python类class继承与多态
Python是一门面向对象语言 面向对象的三大特征:封装、继承、多态 我们这里来看一下python 类的继承 通过继承创建的新类称为子类或派生类,被继承的类称为基类、父类或超类。 一:类的继承 1 :继承语法 arduino 复制代码 class 派生类名(基类名) ... 通常我们定义的类没有指定继承对象都是继承自object类,另外,python是支持多继承的。 下边我们使用代码来演示一下python的继承: 我们定义一个person类,其中有name、age两个属性,getInfo方法,为父类。 我们定义一个school类,其中getSchoolInfo方法,为父类。 定义一
70 0
|
搜索推荐 Python
Python学习 -- 类的继承
Python学习 -- 类的继承
59 0

热门文章

最新文章

推荐镜像

更多