实例方法

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

实例方法栗子

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 - 面向对象编程 - 实例方法、静态方法、类方法的更多相关文章

  1. python类的实例方法\静态方法\类方法区别解析(附代码)

    前言 搞了好久python,一直搞得不太清楚这几种类的方法,今天花时间好好测试一下,算是弄懂点皮毛吧. 三种方法的不同 先剽窃个图看一下 可以看到,实例是三种方法都可以调用的,而类只可以调用两种.所以 ...

  2. python 面向对象编程(一)

    一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法. 类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义: class c ...

  3. Python 面向对象编程基础

    Python 面向对象编程基础 虽然Pthon是解释性语言,但是Pthon可以进行面向对象开发,小到 脚本程序,大到3D游戏,Python都可以做到. 一类: 语法: class 类名: 类属性,方法 ...

  4. python面向对象编程进阶

    python面向对象编程进阶 一.isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 1 ...

  5. 图解python | 面向对象编程

    作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/56 本文地址:http://www.showmeai.tech/article-det ...

  6. python 面向对象编程学习

    1. 问题:将所有代码放入一个py文件:无法维护 方案:如果将代码才分放到多个py文件,好处: 1. 同一个名字的变量互相不影响 2.易于维护 3.引用模块: import module 2.包:解决 ...

  7. Python面向对象编程指南

    Python面向对象编程指南(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1SbD4gum4yGcUruH9icTPCQ 提取码:fzk5 复制这段内容后打开百度网 ...

  8. Python面向对象编程(下)

    本文主要通过几个实例介绍Python面向对象编程中的封装.继承.多态三大特性. 封装性 我们还是继续来看下上文中的例子,使用Student类创建一个对象,并修改对象的属性.代码如下: #-*- cod ...

  9. Python 面向对象编程——访问限制

    <无访问限制的对象> 在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑.但是,从前面Student类的定义来看(见:Py ...

随机推荐

  1. react-router 基本使用

    # 1. 理解react-router react的一个插件库 专门用来实现一个SPA应用 基于react的项目基本都会用到此库 # 2. 几个重要问题## 1). SPA应用 单页Web应用(sin ...

  2. sql-5-事务,索引

    事务 1.ACID概念 原子性(Atomicity) 要么都成功,要么都失败 一致性(consistency) 事务前后的数据完整性保持一致 持久性(Durability) 事务一旦提交则不可逆,持久 ...

  3. 以太坊-Win环境下remix环境搭建

    一.node.js环境搭建 有多个安装方法,但是注意npm与node版本相关性较强!以下方案较为简便 1.下载网址 http://nodejs.cn/download/ 2.下载window 64位 ...

  4. like %和-的区别与使用

    通配符的分类: %百分号通配符:表示任何字符出现任意次数(可以是0次). 下划线通配符:表示只能匹配单个字符,不能多也不能少,就是一个字符. like操作符: LIKE作用是指示mysql后面的搜索模 ...

  5. java命名规则/规范

    Java命名规则: 名称只能由字母.数字.下划线.$符号组成. 不能以数字开头,不能包含空格. 名称不能使用Java中的关键字. Java命名规范: 项目名全部小写:     project 包名全部 ...

  6. php获取当前用户ip

    function wcs_get_onlineip() { $onlineip = ''; if(getenv('HTTP_CLIENT_IP') && strcasecmp(gete ...

  7. 关于win7+cenos 7双系统安装

    ---恢复内容开始--- 1,cenos 0 7制作U盘启动 制作工具 http://pan.baidu.com/s/1nv9lpmp 镜像自备 2,安装centos 7 释放磁盘空间,如:20G.用 ...

  8. SpringCloud升级之路2020.0.x版-4.maven依赖回顾以及项目框架结构

    本系列代码地址:https://github.com/HashZhang/spring-cloud-scaffold/tree/master/spring-cloud-iiford 我们先来回顾下 m ...

  9. UE4 Slate控件之TreeView 使用例子(一)

    TreeView例子 先从Contruct中往子Slot添加Widget,先声明指向STreeView的指针,后续方便进行视图的一些操作 TSharedPtr<STreeView<TSha ...

  10. mybatis动态sql总结

    前言 平时在开发中,针对动态sql这块目前是薄弱点,自己根据官网在对应项目边测试边写博客,此篇只是为了加深动态sql的熟练度,有不到之处敬请批评指正! 1.if 使用动态 SQL 最常见情景是根据条件 ...