目录

1. 静态方法

2. 类方法

3. 抽象方法

4. 绑定

4.1 方法的绑定

4.2 变量的绑定


1. 静态方法

​ 所谓静态方法,即类中不需要与类对象、实例对象绑定的功能,采用 @staticmethod 修饰器修饰,没有 cls 和 self 参数的方法;

静态方法没有 cls、self 参数,因此静态方法中不能调用类中实例变量、实例方法、类方法,但可以通过“类名.静态变量名”、“类名.静态方法”的方式调用类中的静态变量和静态方法;

静态方法同时支持被“类名.静态方法”、“实例名.静态方法”方式调用,参见类和对象:绑定 ;

静态方法调用实例变量、实例方法错误示例如下:

#创建类
class Teststaticmethod1:def __init__(self, name):self.name = namedef hello(self):print('Hello!')#创建调用实例变量的静态方法@staticmethoddef showinfo1():print(f'展示信息:{self.name}')@staticmethoddef showinfo2():print(f'展示信息:{name}')@staticmethoddef showinfo3():print(f'展示信息:{Teststaticmethod1.name}')#创建调用实例方法的静态方法@staticmethoddef sayhello1():hello()@staticmethoddef sayhello2():Teststaticmethod1.hello()#调用实例变量失败
Teststaticmethod1.showinfo1()
Traceback (most recent call last):File "<input>", line 1, in <module>File "<input>", line 10, in showinfo1
NameError: name 'self' is not definedTeststaticmethod1.showinfo2()
Traceback (most recent call last):File "<input>", line 1, in <module>File "<input>", line 13, in showinfo2
NameError: name 'name' is not definedTeststaticmethod1.showinfo3()
Traceback (most recent call last):File "<input>", line 1, in <module>File "<input>", line 16, in showinfo3
AttributeError: type object 'Teststaticmethod1' has no attribute 'name'#调用实例方法失败
Teststaticmethod1.sayhello1()
Traceback (most recent call last):File "<input>", line 1, in <module>File "<input>", line 20, in sayhello1
NameError: name 'hello' is not definedTeststaticmethod1.sayhello2()
Traceback (most recent call last):File "<input>", line 1, in <module>File "<input>", line 23, in sayhello2
TypeError: hello() missing 1 required positional argument: 'self'

静态方法调用静态变量、静态方法,以及被类对象、实例对象调用示例如下:

#创建类
class Teststaticmethod2:name = 'Teststaticmethod'@staticmethoddef hello():print('Hello!')#静态方法中调用静态变量、静态方法@staticmethoddef sayhello():print(f'{Teststaticmethod2.name} say:')Teststaticmethod2.hello()#类对象调用静态方法
Teststaticmethod2.sayhello()
Teststaticmethod say:
Hello!#实例对象调用静态方法
testx = Teststaticmethod2()
testx.sayhello()
Teststaticmethod say:
Hello!

2. 类方法

类方法由类调用,采用 @classmethod 装饰,至少传入一个 cls 参数(代指类本身,类似 self 参数);

执行类方法时,自动将调用该方法的类对象或实例对象,赋值给cls;

类方法同时支持被“类名.类方法”、“实例名.类方法”方式调用,参见类和对象:绑定 ;

类方法通常应用于如下两种情况:

  1. 工厂方法,需要传入类对象,以便在类中创建类的实例对象,完成一些实例对象的预处理工作。
  2. 调用静态方法时,使用 “cls.静态方法名”的方式调用,cls 替代了类名,便于后续维护修改、复用代码时,完美继承新类的各种继承、属性和方法。
#-----------工厂方法--------------------------------------
#创建类
class Testclassmethod1:def __init__(self, var_a, var_b):self.var_a = var_aself.var_b = var_b#定义类方法,可以创建并返回类的实例@classmethoddef newobject(cls, var_a, var_b):return cls(var_a, var_b)#调用类方法,创建实例对象成功
testfactory = Testclassmethod1('test','factory')
x1 = testfactory.newobject('new','1')
x1.var_a
'new'
x1.var_b
'1'#-----------调用静态方法--------------------------------------
#创建类
class Testclassmethod2:#供调用的静态方法@staticmethoddef showinfo(info):print(f'展示信息:{info}')#定义类方法,调用静态方法使用“cls.静态方法名”@classmethoddef newinfo(cls, info):newinfo = f'前四字节缩略【{info[:4]}】'cls.showinfo(newinfo)
#定义等价上述类方法的静态方法,调用静态方法使用“类名.静态方法名”@staticmethoddef newinfo2(info):newinfo = f'前四字节缩略【{info[:4]}】'Testclassmethod2.showinfo(newinfo)#验证静态方法和类方法执行效果
Testclassmethod2.showinfo('0123456789')
展示信息:0123456789
Testclassmethod2.newinfo('0123456789')
展示信息:前四字节缩略【0123】
Testclassmethod2.newinfo2('0123456789')
展示信息:前四字节缩略【0123】

3. 抽象方法

Python 中的抽象方法是父类中一个没有实现的方法;

带有抽象方法的父类不可以实例化,继承该父类的子类必须实现该抽象方法,子类才可以创建实例对象;

为确保带有抽象方法的类不可实例化,可以在抽象方法中添加 raise 语句报错;

但工程师在编写子类时仍可能忘记重新实现抽象方法,直到调用抽象方法时才发现报错,为预防这种情况,可以在抽象方法前添加 abc 模块的 @abstractmethod 装饰器,让子类在编码定义时即发现该问题;

#使用raise语句,提示抽象方法
class Testbase1:def sayhello(self):raise OSError('抽象方法未定义!')class Testderived1(Testbase1):pass#调用抽象方式时报错
testx = Testderived1()
testx.sayhello()
Traceback (most recent call last):File "<input>", line 1, in <module>File "<input>", line 4, in sayhello
OSError: 抽象方法未定义!#使用 @abc.abstractmethod 装饰符,提示抽象方法
import abc
class Testbase2(metaclass = abc.ABCMeta):@abc.abstractmethoddef sayhello(self):passclass Testderived2(Testbase1):pass#创建实例对象时报错
testy = Testderived2()
Traceback (most recent call last):File "<input>", line 1, in <module>
TypeError: Can't instantiate abstract class Testderived2 with abstract method sayhello#子类实现抽象方法后,可以正常创建实例,并调用方法
class Testderived3(Testbase2):def sayhello(self):print('hello')testz = Testderived3()
testz.sayhello()
hello

4. 绑定

类中定义的变量和方法,与实例对象、类对象的对应关系,可以称之为绑定

4.1 方法的绑定

Python 中类的方法通常通过 self 参数传入实例对象后,才能被调用;

类中方法的绑定通常有如下几种情况:

  • 不带 self 参数的方法,本质上是一种没有修饰符的静态方法,只能类对象直接调用,实例对象无法调用;
  • 绑定实例对象的普通实例方法,方法通过 self 参数指向实例对象,类对象调用则报错
  • 绑定类对象的类方法,方法通过 cls 参数指向类对象,实例对象和类对象都可以调用,实例对象实际上通过类对象进行的调用;
  • 不绑定的静态方法,没有 self 参数,实例对象和类对象都可以调用;
#创建类
class Test:#不带 self 参数的方法def testFun1():print('Hi!')
#实例方法,带 self 参数def testFun2(self):print('Come on!')
#类方法@classmethoddef testFun3(cls):print('Let\'s go!')
#静态方法@staticmethoddef testFun4():print('Bye!')#创建类的实例对象
test = Test()#不带 self 参数的方法
#类对象可以调用;实例对象调用,报错
Test.testFun1()
Hi!
test.testFun1()
Traceback (most recent call last):File "<input>", line 1, in <module>
TypeError: testFun1() takes 0 positional arguments but 1 was given#实例方法
#类对象直接调用,报错;实例对象调用后绑定成功,可以调用
Test.testFun2()
Traceback (most recent call last):File "<input>", line 1, in <module>
TypeError: testFun2() missing 1 required positional argument: 'self'
test.testFun2()
Come on!#类方法
#类对象和实例对象都可以正常调用
Test.testFun3()
Let's go!
test.testFun3()
Let's go!#静态方法
#类对象和实例对象都可以正常调用
Test.testFun4()
Bye!
test.testFun4()
Bye!

4.2 变量的绑定

Python 中也存在静态变量和实例变量,静态变量即类中直接赋值的变量,实例变量则是实例方法中以 self. 开头赋值的变量;

静态变量可以直接通过类对象的 __dict__ 属性查询,实例变量则需要创建实例并赋值后在实例对象的 __dict__ 属性中查询;

实例对象中对静态变量重新赋值,则在实例对象中重新创建一个与静态变量同名的实例变量,分别在实例对象和类对象中可以查询得到两个变量不同的值。

#创建类
class TestVar():
#静态变量staticvar = 'Hi!'
#初始化实例变量def __init__(self, name):self.name = name
#实例变量def setvar(self,vara,varb):self.vara = varaself.varb = varb
#调用实例变量的方法def showinfo(self):print(f'{self.name}:{self.vara},{self.varb}')#创建实例对象
testvar = TestVar('TEST')#类对象 __dict__ 属性,可见静态变量
TestVar.__dict__
mappingproxy({'__module__': '__main__', 'staticvar': 'Hi!', '__init__': <function TestVar.__init__ at 0x000001BEC83D6E50>, 'setvar': <function TestVar.setvar at 0x000001BEC83D6CA0>, 'showinfo': <function TestVar.showinfo at 0x000001BEC83D6DC0>, '__dict__': <attribute '__dict__' of 'TestVar' objects>, '__weakref__': <attribute '__weakref__' of 'TestVar' objects>, '__doc__': None})
#类对象无法调用实例变量
TestVar.name
Traceback (most recent call last):File "<input>", line 1, in <module>
AttributeError: type object 'TestVar' has no attribute 'name'#实例对象 __dict__ 属性,可见初始化时已创建的实例变量
testvar.__dict__
{'name': 'TEST'}
#实例对象可以调用静态变量、实例变量
testvar.staticvar
'Hi!'
testvar.name
'TEST'
#尚未创建的实例变量不能调用
testvar.vara
Traceback (most recent call last):File "<input>", line 1, in <module>
AttributeError: 'TestVar' object has no attribute 'vara'#调用函数赋值创建实例变量
testvar.setvar('Aa','Bb')
#实例对象 __dict__ 属性,可见所有已创建的实例变量
testvar.__dict__
{'name': 'TEST', 'vara': 'Aa', 'varb': 'Bb'}
#使用方法调用实例变量正常执行
testvar.showinfo()
TEST:Aa,Bb#实例对象,重新赋值静态变量
testvar.staticvar = 'Hello!'
#实例对象中,可见新的与之前静态变量同名的实例变量
testvar.__dict__
{'name': 'TEST', 'vara': 'Aa', 'varb': 'Bb', 'staticvar': 'Hello!'}
#类对象中,原静态变量不变
TestVar.__dict__
mappingproxy({'__module__': '__main__', 'staticvar': 'Hi!', '__init__': <function TestVar.__init__ at 0x000001BEC83D6E50>, 'setvar': <function TestVar.setvar at 0x000001BEC83D6CA0>, 'showinfo': <function TestVar.showinfo at 0x000001BEC83D6DC0>, '__dict__': <attribute '__dict__' of 'TestVar' objects>, '__weakref__': <attribute '__weakref__' of 'TestVar' objects>, '__doc__': None})

类和对象5:绑定和静态、类、抽象方法相关推荐

  1. Python的类和对象的介绍,定义类和对象,定义实例方法和属性以及Python中的魔法方法

    Day09新手小白学python 第九节 Python的类和对象的介绍,定义类和对象,定义实例方法和属性以及Python中的魔法方法 目录 Day09新手小白学python 前言 一.面向对象介绍 二 ...

  2. 【Java 19】反射 - 反射机制概述、获取Class实例、类的加载与ClassLoader的理解、创建运行时类的对象、获取运行时类的完整结构、调用运行时类的指定结构、动态代理

    反射机制概述.获取Class实例.类的加载与ClassLoader的理解.创建运行时类的对象.获取运行时类的完整结构.调用运行时类的指定结构.动态代理 反射 1 Java反射机制概述 1.1 Java ...

  3. java组合类,对象组合,定义一个点类,将圆的圆心用点类的对象表示,则圆类定义为一个组合类,仍然能计算圆的面积和周长,并能对圆进行移动。

    对象组合的概念 如果一个对象中的域是其他类的对象,则称这个对象是组合对象,组合对象所在的类是组合类.例如计算机是由其他部件(对象)组成的.通过组合的方式,可以简化对象的创建过程,提高对象的创建效率.从 ...

  4. C++模板学习02(类模板)(类模板语法、类模板与函数模板的区别、类模板中的成员函数创建时机、类模板对象做函数参数、类模板与继承、类模板成员函数类外实现、类模板分文件编写、类模板与友元)

    C++引用详情(引用的基本语法,注意事项,做函数的参数以及引用的本质,常量引用) 函数高级C++(函数的默认参数,函数的占位参数,函数重载的基本语法以及注意事项) C++类和对象-封装(属性和行为作为 ...

  5. C++ 类和对象(一):类的概念、类的访问控制和封装、类对象模型、this指针

    类的概念 类的访问控制和封装 类的对象模型 this指针 类的概念 在C++中,类可以说是最重要的东西,因为C++一开始的定位就是c with class,也正是因为引入了类,才让c++从c的面向过程 ...

  6. java 类及对象的课后作业_JAVA类和对象课后作业

    1.使用类的静态字段和构造函数,我们可以跟踪某个类所创建对象的个数.请写一个类,在任何时候都可以向它查询"你已经创建了多少个对象?" 代码: //显示类 //YiMingLai 2 ...

  7. C++类与对象入门实践(日期类的实现)

    日期类 class Date { public://成员函数private:int _year;int _month;int _day; }; 日期类成员对象:  年.月.日 实现功能:  成员函数 ...

  8. python类和对象介绍_python中的类,对象,方法,属性等介绍

    注:这篇文章写得很好.加底纹的是我自己的理解 python中一切皆为对象,所谓对象:我自己就是一个对象,我玩的电脑就是对象,坐着的椅子就是对象,家里养的小狗也是一个对象...... 我们通过描述属性( ...

  9. Kotlin学习笔记 第二章 类与对象 第七节 数据类

    参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...

  10. Java技术笔记1:类与对象实例之系统常用类

    待我君临天下,结发与蕊可好.@夏瑾墨 一直在反思最近的时间安排,知识没有总结和积累很容易发生遗忘,如果要让自己在短期内能有大的提升,那就需要每天的知识流输入,减去你生活中看起来也是重要的东西,然而性命 ...

最新文章

  1. 提升算法的sklearn-kit的API
  2. Java线程池newSingleThreadExecutor newFixedThreadPool newCachedThreadPool newScheduledThreadPool
  3. 如何隐藏 Safari 中 input 标签的 autofill 图标
  4. 【知识分享】异步调用与多线程的区别
  5. Aligned TripletLoss
  6. 海报中应用广泛的书法(手写)字体素材
  7. Linux中/proc目录下文件详解(一)
  8. python适用于哪些芯片_这些鲜为人知的Python功能,你值得拥有!
  9. STM32F4: Generating parallel signals with the FSMC
  10. offer oracle svp_SVP学校转非SVP学校——最新规定详解
  11. android键盘怎么打韩文,手机韩文输入法九键盘如何使用?
  12. cytoscape使用方法_Cytoscape的使用方法(带图片解析)
  13. MySQL入门系列:查询简介(二) 过滤数据
  14. xp系统本地连接服务器,xp系统本地连接受限制或无连接怎么办丨xp本地连接断开无法上网解决办法...
  15. ViewPager的翻页动画
  16. ORACLE ERP consolidation流程(二)
  17. signature=2a6f113e0dca986b5f4efd92dac9c1cb,android so 文件存私密数据,且防止 so文件未知应用盗用...
  18. telnet 和 ping的区别
  19. 硬纪元干货|爱奇艺吴霜:看好互动视频、AI陪伴以及VR直播
  20. 如何在windows上安装虚拟机

热门文章

  1. spark的数三角形算法_腾讯开源全栈机器学习平台 Angel 3.0,支持三大类型图计算算法...
  2. 筋膜枪方案-无刷马达方波运用1
  3. 京东数据分析工具推荐(京东第三方数据平台)
  4. 22MySQL有哪些“饮鸩止渴”提高性能的方法笔记
  5. BF(暴力求解算法)
  6. SurfaceTF卡设置为本地磁盘方法
  7. 今天开始学Convex Optimization:第3章 Convex Sets and Convex functions
  8. 人员属性识别 PETA数据集下载
  9. eharts散点图 调整点的颜色和大小。
  10. 手动引入jar包,解决Dependency ‘XXX‘ not found的两种方式