浅谈python中的面向对象和类的基本语法


Posted in Python onJune 13, 2016

当我发现要写python的面向对象的时候,我是踌躇满面,坐立不安呀。我一直在想:这个坑应该怎么爬?因为python中关于面向对象的内容很多,如果要讲透,最好是用面向对象的思想重新学一遍前面的内容。这个坑是如此之大,犹豫再三,还是只捡一下重要的内容来讲吧,不足的内容只能靠大家自己去补充了。

惯例声明一下,我使用的版本是 python2.7,版本之间可能存在差异。

好,在开讲之前,我们先思考一个问题,看代码:

浅谈python中的面向对象和类的基本语法

为什么我只创建是为 a 赋值,就可以使用一些我没写过的方法?

可能会有小伙伴说:因为 a 此时是个字符串对象呀,当然能够使用字符串的方法,至于这些方法,那是python事先写好的。

好吧,那换个问题,为什么 python 知道它是个字符串对象?

在深入讲这个问题之前,先记住一句话:python中一切皆对象,对象都是由类创建的。

那么类是什么东西呢?我在这举个例子。

有一天,我在街上走着,突然看见前面有一个仇人。此时我想揍他一顿,但是力是相互作用的呀,打他我的拳头也会疼。诶,此时我发现路边有个石头,大小形状正合适,在不考虑警察叔叔怎么想的前提下,这是一个好的选择。然后我抄起石头,对着仇人进行了一些好孩子不能模仿的行为,然后深藏功与名,收工回家。

在这个过程中,我们为什么会知道那块东西是石头?

因为它的具有石头的外观特征呀!

为什么我们会知道石头可以砸人?

因为石头硬呀!

为什么我们知道石头是硬的?

因为......嗯.....小时候我爸告诉我的。

此时可以得到一个结论:我们知道一个东西是什么,具有什么功能,是因为我们的脑海中已经有个这个东西的概念。而这个概念可能是从长辈那里知道的,也可能是自己各种实验后自己总结的。类似于我们对于‘黑洞'这个东西的认识,还是科学家的各种研究总结而来。

如何将用石头打人这个例子用代码来实现的话:

class Stone(object):# 我创建一个叫Stone的类

  def attack(self):
    print '把头伸过来,我给你加个buff'

a = Stone()  # 我用类创建了一个对象,也称为类的实例化
a.attack()   # 我使用这个对象的方法

浅谈python中的面向对象和类的基本语法

很好,这样我们就完成了我们的需要了。

如果我们再创建其他对象:

浅谈python中的面向对象和类的基本语法

很显然python并没有为我们准备 attack 方法,所以就用不了。

所谓的类只是一个抽象的定义,而实例则是具体的对象。它们之间的差别就想我脑海中的石头和我手中的石头一样,只有后者才真实存在。当然,这里不要跟我讲什么唯心主义论什么的。

看到这里,关于类和对象之间的关系应该清楚了一些。有些同学可能会问:python中的类都是我们事先写好的,有没有方法让python自动生成类,然后在特定的时候使用这些类呢?恭喜你,同学,你可能摸到了人工智能的门槛了,如果能够实现的话,那和我们人类的学习能力不是差不多吗?好吧,这只是我的一个设想,真正的人工智能要怎么实现,我也不知道,还没有这么高的水平去研究先,不过作为一名程序员,能够编写人工智能,可能是终身的追求了吧。

在讲完类和实例化是怎么一回事之后,我们来看看类的基本语法。

首先,和定义函数的 def 一样, class 是定义类的关键字。

紧接着的是类名,这个可以自定义,同样的,不能和python的内置关键字冲突。另外,建议避开python的内建类型,例如 str、int之类的名字。规范的命名应该遵从“驼峰命名法”,例如: MyClass 这里的命名,每个单词的首字母大写。

然后是一个括号,里面的参数是用于继承的,一般继承于 object,表示一个新式类。另外,你可能见过没有括号的写法,这是经典类的写法。

示例:

class NewClass(object):
  pass

class OldClass:
  pass

New = NewClass()  # 创建一个新式类的实例
Old = OldClass()  # 创建一个经典类的实例

这就是类的基本语法,当然这样还是不够的,但是在更深入之前,我想先讲一个新旧式类的差别。

在这里,我们先打印一下两个变量的类型:

print type(New)
print type(Old)

浅谈python中的面向对象和类的基本语法

可以看下两者的输出是不同的。

在早于python2.2的版本时,只有经典类这一种写法,当时,类和类型没有合并。

类是类对象,实例是实例对象,这两个对象之间没有任何关系。

这句话是什么意思?看代码:

print type(OldClass)
print type(Old)

浅谈python中的面向对象和类的基本语法

我们可以看见其输出很含糊,经典类属于类对象,无论是哪个类,都统一为“类”类型,实例属于实例类型,却不知道其是由哪个类创建的,所以的实例都统一为“实例”类型。也就是说当时的类型用 classobj 和 instance 代表了所以的类和实例,无论你是哪个类,又或是哪个类创建的实例。

这样的信息实在太少,而类和类型之间非常混乱。为了解决这种情况,在 python2.2 中引入了新式类,并进行了类和类型的同统一。

print type(NewClass)
print type(New)

浅谈python中的面向对象和类的基本语法

类的类型是 type?type 返回的对象还能像类一样创新新对象?

总结的来说:在新式类中,所以的类对象都是 type 的实例。而不同的类对象有能创建出其对应的实例。

class NewClass(object):
  def __init__(self, val):
    self.val = val

New = NewClass(123)  
b = type(New)(321) # 对实例来说type返回的是类对象,我又可以用类对象来和创建新的实例
print b.val

浅谈python中的面向对象和类的基本语法

构造器方法

一般可以理解类中的函数就是方法,而方法分为:实例方法,只有实例化后才能调用的,其第一个参数一般为 self,代表实例本身;类方法,其第一个参数为 cls,代表类本身;还有静态方法,就是个普通函数,没有要求参数。

1. __init__(self [,arg1,....]):

当类被调用进行实例化的时候,python会自动调用类里面的构造函数(如果有的话),在构造函数中,可以进行各种初始化的操作,最常见的就是上面的进行实例的属性的创建。

python 在示例化的时候,会检查其实行了 __init__ 方法了没有,如果没有则不对实例进行任何操作,然后返回对象。如果实行了这个方法,则自动调用这个方法,并自动将 self 传进行,也就是说我们在实例化进行传参的时候,将不用理会 self,直接传给后面的参数。

讲到属性,就必须要提一下什么是属性。属性这个对象其实更像一个变量,大多数对象都可以有属性(不包括python的内置类型),例如函数。

def Test():
  pass

Test.a = 123
print Test.a

浅谈python中的面向对象和类的基本语法

因为函数也是一个对象。

属性在类中,就是一个变量,例如:

class NewClass(object):
  a = 123

print NewClass.a

浅谈python中的面向对象和类的基本语法

当然,因为 python 的特性,我们可以在运作中为某个对象添加属性,而不用一开始就在类中写定。

注意,这个方法应该返回 None,也就是说我们一般不用 return 任何对象,让它默认返回就行了。

2. __new__(cls [,arg1,....]):

这也是一个构造器方法,它是一个类方法,一般在对 python 的不可变数据类型进行继承扩展的时候用的比较多。

某处拿来的代码示例:

class RoundFloat(float):
  def __new__(cls, val):
    return super(RoundFloat, cls).__new__(cls, round(val, 2))

a = RoundFloat(3.14159)
print a

浅谈python中的面向对象和类的基本语法

解构器方法

__del__(self [,arg1,....])

这个方法将会在对象所以的引用被清除后才执行,例如:

class Test(object):

  def __del__(self):
    print '我被干掉了,兄弟们为我报仇!'

a = Test() # 创建了一个对象
b = a  # b又引用了a
c = b  # c又引用了b,现在 a 所指向的对象有3次引用,相当有三条命
del a  # 干掉一条命
del b  # 又干掉
del c  # 听说你有3条命?全部干掉!

浅谈python中的面向对象和类的基本语法

注意,这里只输出了一次,也就是说到了最后才删除完毕。这里要注意一下几点:

1.调用 del 并不意味着完成删除某个对象,只是减少引用。

2.如果你有一个循环引用或其它的原因,让一个实例的引用逗留不去,该对象的__del__()可能永远不会被执行。

3.__del__()未捕获的异常会被忽略掉(因为一些在__del__()用到的变量或许已经被删除了)。 不要在__del__()中干与实例没任何关系的事情。

4.一般情况下并不用实现这个方法,因为这样有一定的风险。

5.如果你定义了__del__,并且实例是某个循环的一部分,垃圾回收器将不会终止这个循环— —你需要自已显式调用 del。

6.如果继承了父类,且父类中也有解构器,要记得调用。否则可能会有某些在父类中的清理方法没有调用到,出现以下无法预料的错误。

以上这篇浅谈python中的面向对象和类的基本语法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中正则表达式的详细教程
Apr 30 Python
python处理二进制数据的方法
Jun 03 Python
Python的Django框架下管理站点的基本方法
Jul 17 Python
基于python元祖与字典与集合的粗浅认识
Aug 23 Python
基于Django模板中的数字自增(详解)
Sep 05 Python
python中数据爬虫requests库使用方法详解
Feb 11 Python
利用scrapy将爬到的数据保存到mysql(防止重复)
Mar 31 Python
对python3 Serial 串口助手的接收读取数据方法详解
Jun 12 Python
Python中的几种矩阵乘法(小结)
Jul 10 Python
Python closure闭包解释及其注意点详解
Aug 28 Python
python并发爬虫实用工具tomorrow实用解析
Sep 25 Python
python 爬取天气网卫星图片
Jun 07 Python
深入理解python多进程编程
Jun 12 #Python
python中根据字符串调用函数的实现方法
Jun 12 #Python
python中函数总结之装饰器闭包详解
Jun 12 #Python
Python备份目录及目录下的全部内容的实现方法
Jun 12 #Python
深入理解python中的闭包和装饰器
Jun 12 #Python
Python编码爬坑指南(必看)
Jun 10 #Python
浅析Python中的for 循环
Jun 09 #Python
You might like
关于在php.ini中添加extension=php_mysqli.dll指令的说明
2007/06/14 PHP
有关PHP性能优化的介绍
2013/06/20 PHP
php使用filter过滤器验证邮箱 ipv6地址 url验证
2013/12/25 PHP
教你如何开启shopnc b2b2c 伪静态
2014/10/21 PHP
php验证码生成代码
2015/11/11 PHP
使用PHPMailer发送邮件实例
2017/02/15 PHP
jquery 学习笔记 传智博客佟老师附详细注释
2020/09/12 Javascript
Javascript 获取滚动条位置等信息的函数
2009/09/08 Javascript
js关闭当前页面(窗口)的几种方式总结
2013/03/05 Javascript
jquery重新播放css动画所遇问题解决
2013/08/21 Javascript
使用JS CSS去除IE链接虚线框的三种方法
2013/11/14 Javascript
JS中使用Array函数shift和pop创建可忽略参数的例子
2014/05/28 Javascript
基于JavaScript怎么实现让歌词滚动播放
2015/11/03 Javascript
BootStrap 超链接变按钮的实现方法
2016/09/25 Javascript
js实现鼠标左右移动,图片也跟着移动效果
2017/01/25 Javascript
Javascript实现时间倒计时效果
2017/07/15 Javascript
javascript按顺序加载运行js方法
2017/12/01 Javascript
Vue的elementUI实现自定义主题方法
2018/02/23 Javascript
Bootstrap Table中的多选框删除功能
2018/07/15 Javascript
vue项目中实现缓存的最佳方案详解
2019/07/11 Javascript
vue实现短信验证码登录功能(流程详解)
2019/12/10 Javascript
微信小程序实现聊天室
2020/08/21 Javascript
[01:05:41]EG vs Optic Supermajor 败者组 BO3 第二场 6.6
2018/06/07 DOTA
[40:04]Secret vs Infamous 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.23
2019/09/05 DOTA
5种Python单例模式的实现方式
2016/01/14 Python
python算法表示概念扫盲教程
2017/04/13 Python
如何使用VSCode愉快的写Python于调试配置步骤
2018/04/06 Python
Python爬虫JSON及JSONPath运行原理详解
2020/06/04 Python
localStorage 设置过期时间的方法实现
2018/12/21 HTML / CSS
AVIS安飞士奥地利租车官网:提供奥地利、欧洲和全世界汽车租赁
2016/11/29 全球购物
悬挂训练绳:TRX
2017/12/14 全球购物
职业规划书如何设计?
2014/01/09 职场文书
临床护理求职信
2014/04/26 职场文书
禁烟标语大全
2014/06/11 职场文书
霸气队列口号
2014/06/18 职场文书
Android Rxjava3 使用场景详解
2022/04/07 Java/Android