Python 面向对象之绑定和非绑定方法

Python 面向对象之绑定和非绑定方法

【一】序言

  • 在Python成员中分为两类:一个是属性,另一个就是方法(就是定义的函数)
  • 方法又分为两大类:绑定方法(动态方法)非绑定方法(静态方法)
  • 从名字上就能知道他们的区别,一个绑定了另一个没有绑定,那么接下来就将具体的讲讲

【二】绑定方法

  • 绑定方法就是指与特定对象关联的方法
  • 它也被分为两大类:绑定给对象的实例方法(对象方法)和绑定给类的类方法

【1】实例方法(对象方法)

(1)概念
  • 绑定到对象上的方法,基本都是为对象服务

  • 没有被任何装饰器装饰的方法

  • 第一个参数时self,实例本身

  • 对象调用实例方法时(对象.实例方法()),自动将对象当作第一个参数传入

  • 类调用实例方法时(类.实例方法(类())),需要手动传入一个实例

  • 一个类的实例方法绑定到不同的对象就是不同的实例方法内存地址各不相同

(2)代码解释
# 绑定给对象,为对象服务
# 没有任何装饰器
class Plant:plant_owner = "戴夫"# 没有装饰器# 这个也是实例方法def __init__(self, name, health, attack_value):self.name = nameself.health = healthself.attack_value = attack_value# 没有装饰器def introduce(self):print(f"""我是{self.name}我的生命值为{self.health},我的攻击力为{self.attack_value},我的主人是{self.plant_owner}""")
# 实例对象
pee_shooter = Plant(name="豌豆射手", health=80, attack_value=10)
# 为对象服务
pee_shooter.introduce()
#         我是豌豆射手
#         我的生命值为80,
#         我的攻击力为10,
#         我的主人是戴夫
# 当对象调用实例方法时,自动将对象当作第一个参数传入
# 当类调用实例方法时,需要手动传入一个实例# 实例化对象
pee_shooter = Plant(name="豌豆射手", health=80, attack_value=10)
# 对象调用实例方法
pee_shooter.introduce_self()
# 实例方法self的内容为:<__main__.Plant object at 0x000001DBD811B970># 类调用实例方法,需要手动传入一个实例
Plant.introduce_self(pee_shooter)
# 一个类的实例方法绑定到不同的实例对象,他们就是不同的实例方法,因为他们地址不同# 实例化对象
sunflower = Plant(name="向日葵", health=100, attack_value=0)
pee_shooter = Plant(name="豌豆射手", health=80, attack_value=10)# 获取类的实例方法的地址
print(id(Plant.introduce))
# 查看绑定到不同对象的实例方法的地址
print(id(sunflower.introduce))
print(id(pee_shooter.introduce))
# 1847514406128             # 地址都不一样
# 1847514372160
# 1847514372096

【2】类方法

(1)概念
  • 绑定到类上的方法,基本都是为类服务

  • classmethod装饰器装饰的方法

  • 第一个参数时cls,类本身

  • 类调用类方法时(类.实例方法()),自动将类当作第一个参数传入

  • 对象调用实例方法时(对象.实例方法()),自动将对象的类当作第一个参数传入

(2)代码解释
# 绑定到类上,为类服务
# 用classmethod装饰器装饰
# 第一个参数是clsclass Plant:plant_owner = "戴夫"plant_rival = "僵尸博士"def __init__(self, name, health, attack_value):self.name = nameself.health = healthself.attack_value = attack_value# 用classmethod装饰器装饰# 第一个参数是cls@classmethoddef introduce_rival(cls):print(f"{cls.__name__}的对手是{cls.__dict__['plant_rival']}")# 为类服务
Plant.introduce_rival()
# 无论是类还是实例调用实例方法,都会自动传入类给cls参数
# 一个类的实例方法绑定到不同的实例对象,他们就是不同的实例方法,因为他们地址不同
class Plant:plant_owner = "戴夫"plant_rival = "僵尸博士"def __init__(self, name, health, attack_value):self.name = nameself.health = healthself.attack_value = attack_value@classmethoddef introduce_rival(cls):print(f"{cls.__name__}的对手是{cls.__dict__['plant_rival']}")# 类调用类方法
print(id(Plant.introduce_rival))
Plant.introduce_rival()
# 1693174119296
# Plant的对手是僵尸博士# 实例化对象
pee_shooter = Plant("豌豆射手", 80,10)
# 实例对象调用类方法
print(id(pee_shooter.introduce_rival))
pee_shooter.introduce_rival()
# 1693174119296                 
# Plant的对手是僵尸博士
  • 可以看到地址相同,即是同一个内容

【三】非绑定方法

  • 非绑定方法就是既没有绑定给类也没有绑定给对象的方法,谁也没有绑定
【1】非绑定方法
(1)概念
  • 不和类也不和对象进行绑定

  • staticmethod装饰器装饰的方法

  • 就是一个普普通通方法(函数),没有特殊的参数

  • 可以在类的外部直接调用(类.非绑定方法())(对象.非绑定方法())

(2)代码解释
class Plant:plant_owner = "戴夫"plant_rival = "僵尸博士"def __init__(self, name, health, attack_value):self.name = nameself.health = healthself.attack_value = attack_value@staticmethoddef static_method():print("这是植物类的静态方法")# 实例化对象
pee_shooter = Plant(name="豌豆射手", health=80, attack_value=10)# 实例访问
print(id(pee_shooter.static_method))
pee_shooter.static_method()
# 2055404428960
# 这是植物类的静态方法# 类访问
print(id(Plant.static_method))
Plant.static_method()
# 2055404428960             # 地址相同
# 这是植物类的静态方法
  • 可以看到地址相同,即是同一个内容

【四】总结

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/317571.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RocketMQ5.0消息过滤

前言 消费者订阅了某个主题后&#xff0c;RocketMQ 会将该主题中的所有消息投递给消费者。若消费者只需要关注部分消息&#xff0c;可通过设置过滤条件在 Broker 端进行过滤&#xff0c;只获取到需要关注的消息子集&#xff0c;避免接收到大量无效的消息。 以电商交易场景为例…

海外住宅IP代理的工作原理和应用场景分析,新手必看

海外住宅IP代理作为一种技术解决方案&#xff0c;为用户提供了访问全球网络资源和维护隐私安全的方法。本文将介绍海外住宅IP代理的工作原理和应用场景&#xff0c;帮助读者更好地理解和利用这一技术。 一、工作原理 海外住宅IP代理的工作原理基于代理服务器和IP地址的转发。它…

Docker实战02|Namespace

在上一文《Docker实战01&#xff5c;容器与开发语言》中主要介绍了Docker的基本概念与Docker安装、Go语言安装等实战技巧。 本文继续针对Namespace技术展开讲解并利用Go语言进行实践。 本系列所有代码均已经开源。关公众号回复「Go语言实现Docker」即可获得。 目录 2.1.2 U…

Spring ApplicationEvent事件处理

Spring的事件 ApplicationEvent以及Listener是Spring为我们提供的一个事件监听、订阅的实现&#xff0c;内部实现原理是观察者设计模式&#xff0c;设计初衷也是为了系统业务逻辑之间的解耦&#xff0c;提高可扩展性以及可维护性。 ApplicationEvent就是Spring的事件接口Applic…

谷歌推出创新SynCLR技术:借助AI生成的数据实现高效图像建模,开启自我训练新纪元!

谷歌推出了一种创新性的合成图像框架&#xff0c;这一框架独特之处在于它完全不依赖真实数据。这个框架首先从合成的图像标题开始&#xff0c;然后基于这些标题生成相应的图像。接下来&#xff0c;通过对比学习的技术进行深度学习&#xff0c;从而训练出能够精准识别和理解这些…

leetcode:1464. 数组中两元素的最大乘积(python3解法)

难度&#xff1a;简单 给你一个整数数组 nums&#xff0c;请你选择数组的两个不同下标 i 和 j&#xff0c;使 (nums[i]-1)*(nums[j]-1) 取得最大值。 请你计算并返回该式的最大值。 示例 1&#xff1a; 输入&#xff1a;nums [3,4,5,2] 输出&#xff1a;12 解释&#xff1a;如…

海外静态IP和动态IP有什么区别?推荐哪种?

什么是静态ip、动态ip&#xff0c;二者有什么区别&#xff1f;哪种好&#xff1f;关于这个问题&#xff0c;不难发现&#xff0c;在知道、知乎上面的解释有很多&#xff0c;但据小编的发现&#xff0c;这些回答都是关于静态ip和动态ip的专业术语解释&#xff0c;普通非专业人事…

一、初识Redis与分布式系统

目录 一、Redis应用 二、实现方式 三、Redis应用 四、分布式系统 五、分布式系统实现 1、应用服务和数据库服务分离 2、引入负载均衡&#xff0c;应用服务器集群&#xff08;解决高并发&#xff09; 3、引入读写分离&#xff0c;数据库主从结构&#xff08;解决高并发&a…

CentOS 7 实战指南:文本处理命令详解

前言 在Linux系统中&#xff0c;文本处理是非常基础却又必不可少的一项技能。如果你正在使用CentOS系统&#xff0c;那么学会如何利用文本操作命令来高效地处理文本文件无疑将会是一个强有力的工具。 本篇文章将介绍一些最常用和最实用的文本操作命令&#xff0c;并通过详尽的…

为什么要用扫码出入库?

一、什么是扫码出入库管理系统 传统的仓库管理模式存在很多问题&#xff0c;如&#xff1a;货物积压、过期、丢失等。这些问题不仅影响了企业的正常运营&#xff0c;还给企业带来了经济损失。为了解决这些问题&#xff0c;扫码出入库管理系统应运而生。该系统采用先进的二维码…

利用蚁剑钓鱼上线CS

前言 ​ 中国蚁剑使用Electron构建客户端软件&#xff0c;Electron实现上用的是Node.js&#xff0c;并且Node.js能执行系统命令&#xff0c;故可以利用蚁剑的webshell页面嵌入js来直接执行命令&#xff0c;进而钓鱼来上线CS。&#xff08;类似Goby&#xff0c;Goby也是使用Ele…

MCMC:Metropolis-Hastings抽样

马尔可夫链有两个要素&#xff1a; 一步转移概率矩阵&#xff1a;初始分布&#xff1a; 如果这两个要素都确定了&#xff0c;这个链的转移行为就被完全确定下来了。我们就可以求得极限分布 &#xff0c;只需解下面这个方程即可。 但是MCMC试图解决的问题刚好是反过来。即已知…