Python类调用实例方法

在 Python 的类体中定义的方法默认都是实例方法,通过对象来调用实例方法。

但要提醒大家的是,Python 的类在很大程度上是一个命名空间,当程序在类体中定义变量、方法时,与前面介绍的定义变量、定义函数其实并没有太大的不同。对比如下代码:

# 定义全局空间的foo函数
def foo ():print("全局空间的foo方法")
# 全局空间的bar变量
bar = 20
class Bird:# 定义Bird空间的foo函数def foo():print("Bird空间的foo方法")# 定义Bird空间的bar变量bar = 200
# 调用全局空间的函数和变量
foo()
print(bar)
# 调用Bird空间的函数和变量
Bird.foo()
print(Bird.bar)

上面代码在全局空间和 Bird 类(Bird 空间)中分别定义了 foo() 函数和 bar 变量,从定义它们的代码来看,几乎没有任何区别,只是在 Bird 类中定义它们时需要缩进。

接下来程序在调用 Bird 空间内的 bar 变量和 foo() 函数(方法)时,只要添加 Bird. 前缀即可,这说明完全可以通过 Bird 类来调用 foo() 函数(方法)。这就是类调用实例方法的证明。

现在问题来了,如果使用类调用实例方法,那么该方法的第一个参数(self)怎么自动绑定呢?例如如下程序:

class User:def walk (self):print(self, '正在慢慢地走')
# 通过类调用实例方法
User.walk()

运行上面代码,程序会报出如下错误:

TypeError: walk() missing 1 required positional argument:'self'

请看程序最后一行代码,调用 walk() 方法缺少传入的 self 参数,所以导致程序出错。这说明在使用类调用实例方法时,Python 不会自动为第一个参数绑定调用者。实际上也没法自动绑定,因此实例方法的调用者是类本身,而不是对象。

如果程序依然希望使用类来调用实例方法,则必须手动为方法的第一个参数传入参数值。例如,将上面的粗体字代码改为如下形式:

u = User()
# 显式为方法的第一个参数绑定参数值
User.walk(u)

此代码显式地为 walk() 方法的第一个参数绑定了参数值,这样的调用效果完全等同于执行 u.walk()。

实际上,当通过 User 类调用 walk() 实例方法时,Python 只要求手动为第一个参数绑定参数值,并不要求必须绑定 User 对象,因此也可使用如下代码进行调用:

# 显式为方法的第一个参数绑定fkit字符串参数值
User.walk('fkit')

如果按上面方式进行绑定,那么 'fkit' 字符串就会被传给 walk() 方法的第一个参数 self。因此,运行上面代码,将会看到如下输出结果:

fkit 正在慢慢地走

总结

Python 的类可以调用实例方法,但使用类调用实例方法时,Python 不会自动为方法的第一个参数 self 绑定参数值;程序必须显式地为第一个参数 self 传入方法调用者。这种调用方式被称为“未绑定方法”。

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

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

相关文章

解析神器Xpath详解+实战

解析神器Xpath详解实战 有同学说,我正则用的不好,处理HTML文档很累,有没有其他的方法? 有!那就是XPath,我们可以先将 HTML文件 转换成 XML文档,然后用 XPath 查找 HTML 节点或元素。 目标&am…

微信小程序怎样给事件传值的

微信小程序怎样给事件传值的? 通过自定义属性传值通过事件对象传值 通过自定义属性传值 通过自定义属性传值: 在触发事件的组件上,可以通过自定义属性将需要传递的值绑定到事件对象上。在事件处理函数中,通过event.currentTarget.…

【KMP】【判断是否是重复子字符串】Leetcode 459 重复的子字符串

【KMP】【判断是否是重复子字符串】Leetcode 459 重复的子字符串 解法1 拼接字符串-掐头去尾后判断是否含有原字符串解法2 KMP——重复子串的最小单位是这个字符串里的最长相等前后缀所不包含的子串解法3 暴力解法KMP ---------------🎈🎈题目链接&…

【C++11特性篇】一文助小白轻松理解 C++中的【左值&左值引用】【右值&右值引用】

前言 大家好吖,欢迎来到 YY 滴C系列 ,热烈欢迎! 本章主要内容面向接触过C的老铁 主要内容含: 欢迎订阅 YY滴C专栏!更多干货持续更新!以下是传送门! 目录 一.【左值&左值引用】&…

C#中简单的继承和多态

今天我们来聊一聊继承,说实话今天也是我第一次接触。 继承的概念是什么呢?就是一个类可以继承另一个类的属性和方法(成员) 继承是面向对象编程中的一个非常重要的特性。 好了,废话不多说,下面切入正题&a…

微信小程序使用camera扫码获取相机权限

确保用户隐私指引已经明确使用相机功能 “mp-weixin”: "permission": {"scope.camera": {"desc": "需要使用相机功能,请授权"}}wx.authorize({scope: scope.camera,success(res) {console.log(res, 用户成功授权)// 用户…

C语言实现Hoare版快速排序(递归版)

Hoare版 快速排序是由Hoare发明的,所以我们先来讲创始人的想法。我们直接切入主题,Hoare版快速排序的思想是将一个值设定为key,这个值不一定是第一个,如果你选其它的值作为你的key,那么你的思路也就要转换一下&#xf…

Mysql(事务)

Mysql(事务) 简介 是什么:一组操作的集合,不分割的工作单位,事务会把所有的操作作为一个整体,向数据库发起操作,要么全部失败要么全部成功。 案例: 银行转账 查询A的余额减少的A的余…

input , change ,blur 事件的区别,以及在vue和react中的表现

原生事件介绍 onInput Event 当一个 , , 或 元素的 value 被修改时,会触发 input 事件 onChange Event 当用户更改 、 和 元素的值时,change 事件在这些元素上触发。和 input 事件不同的是,并不是每次元素的 value 改变时都会触发 change…

SQL 算术运算符

SQL Server中的存储过程 什么是存储过程? 存储过程是一段预先编写好的 SQL 代码,可以保存在数据库中以供反复使用。它允许将一系列 SQL 语句组合成一个逻辑单元,并为其分配一个名称,以便在需要时调用执行。存储过程可以接受参数…

Qt线程池

创建一个类继承自QRunnable&#xff1a; class Thread02 : public QRunnable 重写run方法&#xff1a; void run() override; 在main函数里面加入线程池&#xff1a; Thread02 *th new Thread02();QThreadPool::globalInstance()->start(th); #include <QtCore/QC…

巧妙的使用WPF中的资源

其实&#xff0c;在wpf中&#xff0c;最核心的就是xaml&#xff0c;因为只有xaml&#xff0c;才能体现出用的是wpf&#xff0c;而不是普通的cs文件&#xff0c;cs文件在winform中等等程序都可以使用的&#xff0c;唯独xaml才是wpf中最重要的&#xff0c;最精华的东西&#xff0…

ARM按键中断

do_irq.c 判断中断号 #include "key_it.h" extern void printf(const char *fmt, ...); unsigned int i 0; void do_irq(void) {// 获取中断号&#xff0c;根据中断号的不同进行不同的中断处理int irqno;irqno GICC->IAR & 0x3ff;switch (irqno){case 99:…

gitlab ci pages

参考文章 gitlab pages是什么 一个可以利用gitlab的域名和项目部署自己静态网站的机制 开启 到gitlab的如下页面 通过gitlab.ci部署项目的静态网站 # build ruby 1/3: # stage: build # script: # - echo "ruby1"# build ruby 2/3: # stage: build …

jupyter notebook介绍、安装和使用

简介 Jupyter Notebook是基于网页的用于交互计算的应用程序。其可被应用于全过程计算&#xff1a;开发、文档编写、运行代码和展示结果。——Jupyter Notebook官方介绍 简而言之&#xff0c;Jupyter Notebook是以网页的形式打开&#xff0c;可以在网页页面中直接编写代码和运…

vue3 + ts 判断各种数据类型,首字母转大写,下划转驼峰,的方法集合

vue3 ts 判断各种数据类型&#xff0c;首字母转大写&#xff0c;下划转驼峰&#xff0c;的方法集合(记录ing…) 1. 直接上代码 1. 在utils文件夹下新建 index.ts// index.ts/*** description: 判断是否为某个类型*/ export function is(val: unknown, type: string) {return …

SpringCache入门

1. SpringCache概述 Spring Cache 是 Spring 框架提供的一个用于提高应用性能的缓存抽象。它不是一个具体的缓存实现&#xff0c;而是提供了一组一致的编程模型来整合各种缓存机制&#xff0c;比如 EhCache、Caffeine、Redis 等。Spring Cache 使得开发者可以通过简单的注解来…

Spring Boot+Mybatis设置sql日志打印

在全局配置文件添加以下内容&#xff1a;logging.level.com.demo.mapperdebug&#xff0c;com.demo.mapper&#xff1a;src下的mapper路径&#xff0c;debug&#xff1a;设置日志打印级别为debug&#xff0c;亦可设置为&#xff1a;ERROR、WARN、INFO application.properties …

10-流媒体-RTMP编译

将h264推流给服务器&#xff0c;就完成了采集端的推流工作。一般在嵌入式系统常用的rtmp推流方案是rtmpdump。使用rtmp库涉及到一些编译过程&#xff0c;下面我们一点点描述。 关于rtmp的使用涉及到3个开源库的编译&#xff08;openssl, zlib, rtmpdump&#xff09;&#xff0c…

【C++】optional的使用(一)

这篇文章介绍下C17引入的std::optional 为什么要有 optional 一般来说&#xff0c;如果想要一个函数返回“多个”值&#xff0c;C程序员倾向于使用结构体/类完成这个操作。即定义一个通用的结构体&#xff0c;在函数内部完成装填&#xff0c;然后返回一个实例化的结构体。 #…