前言

本节将是Python面向对象的最后一篇博文了,这节将记录类的特殊方法、特殊成员方法、旧类和新类的不同,以及一些其他知识。Go!

一、类的特殊方法

Python有三种特殊方法:实例方法、静态方法、类方法。如果你读过一些源代码,你一定疑惑过这些代码:@staticmethod、@classmethod,前面见到的所有方法都是实例方法,实例方法的第一个参数为实例本身(self),由于实例方法经过前面几节已经掌握,所有本节将会熟悉剩下的两种特殊方法

1.1 静态方法

之前在类中编写的各种方法其实都是属于实例方法,每一个方法的第一个参数是实例本身(self),实例方法固然好用,但是在开发中,需要一些这样的方法:与类有关,在使用时不需要引用类和实例,也就是不能访问类变量和实例变量。这些方法通常用来作全局的配置方法,使代码更加简洁和安全。

1.1.1 创建静态方法

在类中的方法的前面使用装饰器: @staticmethod 即可,静态方法已经和普通函数没有太大区别,唯一的区别就是静态方法要通过对象来访问,看例:

 class Teacher:
def __init__(self, name, gender):
self.name = name
self.gender = gender def talk(self):
print('I am {}'.format(self.name)) @staticmethod # 创建 is_man 静态方法
def is_man(gender):
if gender == 'male':
return 1
return 0

通过上例可以看到静态方法的创建比较简单,基本上已经和类无关了,按照普通的函数创建即可

1.1.2 调用静态方法

静态方法与函数的区别就是调用方式不同,函数直接调用即可,但是静态方法多多少少和类还是有一些关系的,那就是调用时需要对象来调用:

zhangsan = Teacher('zhangsan', 'male')

print(zhangsan.is_man('male'))

# 运行结果:
1

注意:静态方法无法调用类变量和实例变量,这里就不作演示了。

『防抄袭:读者请忽略这段文字,文章作者是博客园的MinuteSheep

但是静态方法通常并不会在类外调用静态方法,而是直接在类内作为全局配置方法使用,例如:

 class Teacher:
def __init__(self, name, gender):
self.name = name
self.gender = gender def talk(self):
print('I am {}'.format(self.name)) @staticmethod
def is_man(gender):
if gender == 'male':
return 1
return 0 def eat(self):
flag = self.is_man(self.gender) # 作为全局配置使用
if flag:
print('I am man, I will eat 2 buns')
else:
print('I am woman, I will eat 1 bun') zhangsan = Teacher('zhangsan', 'male') zhangsan.eat()
# 运行结果:
I am man, I will eat 2 buns

1.1.3 继承静态方法

如果超类中有静态方法时,子类继承时会发生什么呢?

class Teacher(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender @staticmethod
def is_man(gender):
if gender == 'male':
return 1
return 0 def eat(self):
flag = self.is_man(self.gender) # 作为全局配置使用
if flag:
print('I am {}, I will eat 2 buns'.format(flag))
else:
print('I am {}, I will eat 1 bun'.formar(flag)) class Chinese(Teacher):
'''
创建一个语文老师类,
继承Teacher
''' def __init__(self, name, gender):
super().__init__(name, gender) @staticmethod # 改写超类的静态方法
def is_man(gender):
if gender == 'male':
return 'man'
return 'woman' zhangsan = Chinese('zhangsan', 'male') zhangsan.eat()

继承后将超类静态方法改写,运行结果j将按照子类的静态方法运行,结果如下:

# 运行结果:
I am man, I will eat 2 buns # 而不是按照超类的静态方法
# I am 1,I will eat 2 buns

1.2 类方法

类方法,顾名思义是一种直接作用于类的方法。类方法和实例方法的区别就在于:类方法只能访问类变量,不能访问实例变量。

1.2.1 创建类方法

在类中的方法前面使用装饰器: @classmethod 即可,类方法和实例方法格式相似,类方法第一个参数必须是类本身(cls),看例:

class Teacher(object):
food = 'bun' def __init__(self, name, gender):
self.name = name
self.gender = gender @classmethod # 创建类方法 eat
def eat(cls):
print(cls.food)

通过上面代码可以看到,类方法的第一个参数为类本身,习惯上用cls表示,当然也可以用其他单词表示(这一点与self类似)

1.2.2 调用类方法

类方法的调用与实例方法无异,看例:

zhangsan = Teacher('zhangsan', 'male')
zhangsan.eat() # 运行结果:
bun

注意:类方法只能调用类变量,不能调用实例变量,这里就不作演示了

『防抄袭:读者请忽略这段文字,文章作者是博客园的MinuteSheep

类方法经常出现在源代码中,通常用来为类传入新的参数。

二、类的特殊成员方法

什么事特殊成员方法呢?其实你已经见过了,那就是类似__init__这样 __方法__ 形式的方法

2.1 常用的特殊成员方法

__init__   「构造函数,当实例化类对象时,会自动调用该方法」

class Test:
def __init__(self):
print('实例化类对象后就会运行我') Test() # 运行结果:
实例化类对象后就会运行我

__del__   「析构函数,当类对象在内存中被释放时(也就是类对象运行完后),会自动调用该方法」

class Test:
def __del__(self):
print('类对象释放后就会运行我') Test() # 运行结果:
类对象释放后就会运行我

__call__   「call方法,在类或者对象后加括号执行该方法」

class Test:
def __call__(self):
print('我是博客园MinuteSheep,神马文库抄袭我的博文,不要脸') Test()()
# 或者
# obj = Test()
# obj() # 运行结果:
我是博客园MinuteSheep,神马文库抄袭我的博文,不要脸

__dict__   「dict方法,查看类或者对象的所有成员信息」

class Test:
x = 1000
y = 'MS' print(Test.__dict__) # 运行结果:
{'__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Test' objects>, 'x': 1000, '__doc__': None, 'y': 'MS', '__dict__': <attribute '__dict__' of 'Test' objects>}

__doc__   「doc方法,查看类的描述信息」

class Test:
'''
这里是类的描述信息
'''
x = 1000
y = 'MS' print(Test.__doc__) # 运行结果: 这里是类的描述信息

三、旧类与新类

Python3中,只有新类,旧类以及被移除, class 类名: 和 class 类名(object): 都是新类;Python2中, class 类名: 是旧类, class 类名(object): 是新类

对旧类和新类了解一下即可

3.1 旧类与新类的区别

旧类:深度优先

新类:广度优先

 # 在Python2中

 class A:
pass class B(A):
pass class C(B):
pass class D(A, B, C):
pass D()

在Python2中,上述代码的调用顺序为:D->A->B->A->C->B->A

明显是深度优先

 # 在Python2中

 class A(object):
pass class B(A):
pass class C(B):
pass class D(A, B, C):
pass D()

在Python2中,上诉代码的调用顺序为:D->A->B->C->A->B->A->object

明显是广度优先

四、其他知识

4.1 私有成员和私有方法

接触类这么久了,你一定发现了又的方法和成员没有下划线,有的方法和成员只有一条下划线,有的方法和成员首尾各有两条下划线,这到底是什么含义呢?

  • 无下划线 foo:表示普通方法和成员

  • 一条下划线 _foo:表示被保护方法和成员,不能被 from xxx import _foo 导入

  • 两条下划线 __foo:表示私有方法和成员,只运行类本身进行访问

  • 首尾各两条下划线 __foo__:表示特殊方法,一般由系统自定义

结语

Python面向对象的知识到此结束,多加理解和联系才能真正掌握面向对象的知识,拜拜~

#5 Python面向对象(四)的更多相关文章

  1. python 面向对象四 继承和多态

    一.继承 class Animal(object): def run(self): print('Animal is running...') class Dog(Animal): def run(s ...

  2. Python 面向对象(四) 反射及其魔术方法

    反射 reflection 也有人称之为自省 作用: 运行时获取.添加对象的类型定义信息,包括类 内建方法: getattr(object, name[, default])   返回object对象 ...

  3. python 面向对象(四)反射

    ####################总结########## 1. isinstance: 判断xxx是否是xxx类型的(向上判断) type: 返回xx对象的数据类型 issubclass: 判 ...

  4. Python 基础 四 面向对象杂谈

    Python 基础  四  面向对象杂谈 一.isinstance(obj,cls) 与issubcalss(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls ...

  5. Python之面向对象四

    面向对象进阶 一.关于面向对象的两个内置函数 isinstance   判断类与对象的关系    isinstance(obj,cls)检查obj是否是类 cls 的对象,返回值是bool值 issu ...

  6. python 面向对象专题(四):封装、多态、鸭子类型、类的约束、super

    https://www.cnblogs.com/liubing8/p/11321099.html 目录 Python面向对象04 /封装.多态.鸭子类型.类的约束.super 1. 封装 2. 多态 ...

  7. python面向对象进阶(八)

    上一篇<Python 面向对象初级(七)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使 ...

  8. python 面向对象(进阶篇)

    上一篇<Python 面向对象(初级篇)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使 ...

  9. python 面向对象学习

    ------Python面向对象初 下面写一个类的简单实用,以便方便理解类 #python 3.5环境,解释器在linux需要改变 #阅读手册查询readme文件 #作者:S12-陈金彭 class ...

随机推荐

  1. js活jQuery实现动态添加、移除css/js文件

    下面是在项目中用到的,直接封装好的函数,拿去在js中直接调用就可以实现css.js文件的动态引入与删除.代码如下 动态加载,移除,替换css/js文件 // 动态添加css文件 function ad ...

  2. idea设置调用方法时提示方法注释

    如图所示:打开file-->setting-->Editor-->General,搜索show,然后勾选上Show quick documentation on mouse move ...

  3. 【前端性能】Web 动画帧率(FPS)计算

    我们知道,动画其实是由一帧一帧的图像构成的.有 Web 动画那么就会存在该动画在播放运行时的帧率.而帧率在不同设备不同情况下又是不一样的. 有的时候,一些复杂或者重要动画,我们需要实时监控它们的帧率, ...

  4. CoreProfiler升级到.NetStandard 2.0

    致所有感兴趣的朋友: CoreProfiler和相应的Sample项目cross-app-profiling-demo都已经升级到.NetStandrard 2.0和.NetCore 2.0. 有任何 ...

  5. 【安富莱专题教程第5期】工程调试利器RTT实时数据传输组件,替代串口调试,速度飞快,可以在中断和多任务中随意调用

    说明:1.串口作为经典的调试方式已经存在好多年了,缺点是需要一个专门的硬件接口.现在有了SEGGER的RTT(已经发布有几年了),无需占用系统额外的硬件资源,而且速度超快,是替代串口调试的绝佳方式.2 ...

  6. SQL基本注入演示

    作者:ZERO 所属团队:Arctic Shell 参考文献:<sql注入攻击与防御> 使用平台:pikachu漏洞练习平台 导语:  在owasp发布的top10排行榜中注入漏洞一直是危 ...

  7. Angularjs中的缓存以及缓存清理

    写在最前面:这篇博文是2篇文章组成,详细介绍了Angularjs中的缓存以及缓存清理,文章由上海尚学堂转载过来,欢迎大家阅读和评论.转载请注明出处,谢谢! 一个缓存就是一个组件,它可以透明地储存数据, ...

  8. Git漏洞允许任意代码执行(CVE-2018-17456)复现

    Git漏洞允许任意代码执行(CVE-2018-17456) 国外安全研究员 joernchen 在 9 月 23 日向 git 官方报告了漏洞的相关细节.10月5日,Git项目披露了一个漏洞,编号为C ...

  9. 文本编辑器激活系列(一):Sublime 安装、激活、汉化教程

    如您激活出现问题,请点击这里加入:软件激活问题解决群 前言 推荐几款文本编辑器: Sublime:内嵌python解释器.大量插件 EditPlus:语法着色.内嵌浏览器 Notepad++:所见即所 ...

  10. Spring mvc参数类型转换

    1,需求 有时候我们接收到的参数为String类型的,但是我们需要将它们转化为其他类型的如:date类型,枚举类型等等,spring mvc为我们提供了这样的功能. 2,配置文件 在springmvc ...