Python(十八)

一 什么是面向对象的程序设计及为什么要有它

面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西。

优点是:极大的降低了程序的复杂度

缺点是:一套流水线或者流程就是用来解决一个问题,生产汽水的流水线无法生产汽车,即便是能,也得是大改,改一个组件,牵一发而动全身。

应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。

面向对象的程序设计的核心是对象(上帝式思维),要理解对象为何物,必须把自己当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也可以创造出来。面向对象的程序设计好比如来设计西游记,如来要解决的问题是把经书传给东土大唐,如来想了想解决这个问题需要四个人:唐僧,沙和尚,猪八戒,孙悟空,每个人都有各自的特征和技能(这就是对象的概念,特征和技能分别对应对象的数据属性和方法属性),然而这并不好玩,于是如来又安排了一群妖魔鬼怪,为了防止师徒四人在取经路上被搞死,又安排了一群神仙保驾护航,这些都是对象。然后取经开始,师徒四人与妖魔鬼怪神仙交互着直到最后取得真经。如来根本不会管师徒四人按照什么流程去取。

面向对象的程序设计的

优点是:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。

缺点:可控性差,无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即便是上帝也无法预测最终结果。于是我们经常看到一个游戏人某一参数的修改极有可能导致阴霸的技能出现,一刀砍死3个人,这个游戏就失去平衡。

应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方

面向对象的程序设计并不是全部。对于一个软件质量来说,面向对象的程序设计只是用来解决扩展性。

二 类和对象

2.1 什么是对象,什么是类

  提示:python的class术语与c++有一定区别,与 Modula-3更像。

  python中一切皆为对象,且python3统一了类与类型的概念,类型就是类,所以,不管你信不信,你已经使用了很长时间的类了

1 >>> dict #类型dict就是类dict
2 <class ‘dict‘>
3 >>> d=dict(name=‘egon‘) #实例化
4 >>> d.pop(‘name‘) #向d发一条消息,执行d的方法pop
5 ‘egon‘

  基于面向对象设计一个款游戏:英雄联盟,每个玩家选一个英雄,每个英雄都有自己的特征和和技能,特征即数据属性,技能即方法属性,特征与技能的结合体就一个对象。

  从一组对象中提取相似的部分就是类所有对象都具有的特征和技能的结合体

  在python中,用变量表示特征,用函数表示技能,因而类是变量与函数的结合体,对象是变量与方法(指向类的函数)的结合体

  

  补充几个有意思的点:

  garen_hero.Q()称为向garen_hero这个对象发送了一条消息,让他去执行Q这个函数,完成一个功能,类似的有:

  garen_hero.W()

  garen_hero.E()

  garen_hero.R()

  一个英雄可以攻击另外一个英雄,这就是对象之间的交互

  garen_hero.attack(Riven)

2.2 类相关知识

2.2.1 初识类

在python中声明函数与声明类很相似

声明函数

1 def functionName(args):
2      ‘函数文档字符串‘
3       函数体 

声明类

 1 ‘‘‘
 2 class 类名:
 3     ‘类的文档字符串‘
 4     类体
 5 ‘‘‘
 6
 7 #我们创建一个类
 8 class Data:
 9     pass 

在本节开头介绍得出结论,类是数据与函数的结合,二者称为类的属性

class Garen:        #定义英雄盖伦的类,不同的玩家可以用它实例出自己英雄;
    camp=‘Demacia‘  #所有玩家的英雄(盖伦)的阵营都是Demacia;
    def attack(self,enemy):   #普通攻击技能,enemy是敌人;
        enemy.life_value-=self.aggressivity #根据自己的攻击力,攻击敌人就减掉敌人的生命值。

2.2.2 类有两种作用:属性引用和实例化

2.2.2.1 属性引用(类名.属性)

>>> Garen.camp #引用类的数据属性,该属性与所有对象/实例共享
‘Demacia‘
>>> Garen.attack #引用类的函数属性,该属性也共享
<function Garen.attack at 0x101356510>
>>> Garen.name=‘Garen‘ #增加属性
>>> del Garen.name #删除属性

2.2.2.2 实例化(__init__与self)

类名加括号就是实例化,会自动触发__init__函数的运行,可以用它来为每个实例定制自己的特征

class Garen:        #定义英雄盖伦的类,不同的玩家可以用它实例出自己英雄;
    camp=‘Demacia‘  #所有玩家的英雄(盖伦)的阵营都是Demacia;
    def __init__(self,nickname,aggressivity=58,life_value=455): #英雄的初始攻击力58...;
        self.nickname=nickname  #为自己的盖伦起个别名;
        self.aggressivity=aggressivity #英雄都有自己的攻击力;
        self.life_value=life_value #英雄都有自己的生命值;
    def attack(self,enemy):   #普通攻击技能,enemy是敌人;
        enemy.life_value-=self.aggressivity #根据自己的攻击力,攻击敌人就减掉敌人的生命值。

实例化:类名+括号

>>> g1=Garen(‘草丛伦‘) #就是在执行Garen.__init__(g1,‘草丛伦‘),然后执行__init__内的代码g1.nickname=‘草丛伦’等

self的作用是在实例化时自动将对象/实例本身传给__init__的第一个参数,self可以是任意名字,但是瞎几把写别人就看不懂了。

这种自动传递的机制还体现在g1.attack的调用上,后续会介绍。

2.3 对象相关知识

对象是关于类而实际存在的一个例子,即实例

>>> g1=Garen(‘草丛伦‘) #类实例化得到g1这个实例,基于该实例我们讲解实例相关知识
>>> type(g1) #查看g1的类型就是类Garen
<class ‘__main__.Garen‘>
>>> isinstance(g1,Garen) #g1就是Garen的实例
True

2.3.1 对象/实例只有一种作用:属性引用

#对象/实例本身其实只有数据属性
>>> g1.nickname
‘草丛伦‘
>>> g1.aggressivity
58
>>> g1.life_value
455
‘‘‘
查看实例属性
同样是dir和内置__dict__两种方式
特殊实例属性
__class__
__dict__
....
‘‘‘

对象/实例本身只有数据属性,但是python的class机制会将类的函数绑定到对象上,称为对象的方法,或者叫绑定方法,绑定方法唯一绑定一个对象,同一个类的方法绑定到不同的对象上,属于不同的方法,内存地址都不会一样

>>> g1.attack #对象的绑定方法
<bound method Garen.attack of <__main__.Garen object at 0x101348dd8>>

>>> Garen.attack #对象的绑定方法attack本质就是调用类的函数attack的功能,二者是一种绑定关系
<function Garen.attack at 0x101356620>

对象的绑定方法的特别之处在于:obj.func()会把obj传给func的第一个参数。

2.4 对象之间的交互

我们可以仿照garen类再创建一个Riven类

class Riven:
    camp=‘Noxus‘  #所有玩家的英雄(锐雯)的阵营都是Noxus;
    def __init__(self,nickname,aggressivity=54,life_value=414): #英雄的初始攻击力54;
        self.nickname=nickname  #为自己的锐雯起个别名;
        self.aggressivity=aggressivity #英雄都有自己的攻击力;
        self.life_value=life_value #英雄都有自己的生命值;
    def attack(self,enemy):   #普通攻击技能,enemy是敌人;
        enemy.life_value-=self.aggressivity #根据自己的攻击力,攻击敌人就减掉敌人的生命值。 

实例出一个Riven来

>>> r1=Riven(‘锐雯雯‘)

交互:锐雯雯攻击草丛伦,反之一样

>>> g1.life_value
455
>>> r1.attack(g1)
>>> g1.life_value
401 

2.5 类名称空间与对象/实例名称空间

创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性

而类有两种属性:数据属性和函数属性

其中类的数据属性是共享给所有对象的

>>> id(r1.camp) #本质就是在引用类的camp属性,二者id一样
4315241024
>>> id(Riven.camp)
4315241024

而类的函数属性是绑定到所有对象的:

>>> id(r1.attack)
4302501512
>>> id(Riven.attack)
4315244200

‘‘‘
r1.attack就是在执行Riven.attack的功能,python的class机制会将Riven的函数属性attack绑定给r1,r1相当于拿到了一个指针,指向Riven类的attack功能

除此之外r1.attack()会将r1传给attack的第一个参数
‘‘‘

创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性

在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常

时间: 2024-12-13 02:59:48

Python(十八)的相关文章

python(十八):cookie和session

一.Cookie 1.cookie机制 会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份. 在程序中,会话跟踪是很重要的事情.理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆.例如,用户A在超市购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,这都

Python之路【第十八篇】:Web框架们

Python之路[第十八篇]:Web框架们 Python的WEB框架 Bottle Bottle是一个快速.简洁.轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Python的标准库外,其不依赖任何其他模块. 1 2 3 4 pip install bottle easy_install bottle apt-get install python-bottle wget http://bottlepy.org/bottle.py Bottle框架大致可以分为以下部分: 路

【Python之路】第十八篇--MySQL(一)

[Python之路]第十八篇--MySQL(一) 一.概述 1.什么是数据库 ? 答:数据的仓库,如:在ATM的示例中我们创建了一个 db 目录,称其为数据库 2.什么是 MySQL.Oracle.SQLite.Access.MS SQL Server等 ? 答:他们均是一个软件,都有两个主要的功能: a. 将数据保存到文件或内存 b. 接收特定的命令,然后对文件进行相应的操作 PS:如果有了以上软件,无须自己再去创建文件和文件夹,而是直接传递 命令 给上述软件,让其来进行文件操作,他们统称为数

Python开发【第十八篇】:MySQL(二)

Python开发[第十八篇]:MySQL(二) 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用. SELECT * FROM ( SELECT nid, NAME FROM tb1 WHERE nid > 2 ) AS A WHERE A. NAME > 'alex'; 临时表搜索 1.创建视图 --格式:CREATE VIEW 视图名称 AS SQL语句 CREATE VIEW v

QT开发(三十八)——Model/View框架编程

QT开发(三十八)--Model/View框架编程 一.自定义模型 1.自定义只读模型 QAbstractItemModel为自定义模型提供了一个足够灵活的接口,能够支持数据源的层次结构,能够对数据进行增删改操作,还能够支持拖放.QT提供了 QAbstarctListModel和QAbstractTableModel两个类来简化非层次数据模型的开发,适合于结合列表和表格使用. 自定义模型需要考虑模型管理的的数据结构适合的视图的显示方式.如果模型的数据仅仅用于列表或表格的显示,那么可以使用QAbs

COS访谈第十八期:陈天奇

COS访谈第十八期:陈天奇 [COS编辑部按] 受访者:陈天奇      采访者:何通   编辑:王小宁 简介:陈天奇,华盛顿大学计算机系博士生,研究方向为大规模机器学习.他曾获得KDD CUP 2012 Track 1第一名,并开发了SVDFeature,XGBoost,cxxnet等著名机器学习工具,是Distributed (Deep) Machine Learning Common的发起人之一. 何:你的本科在上海交大的ACM班就读,是怎么开始做机器学习研究的呢? 陈:我们当时的培养计划

Redis进阶实践之十八 使用管道模式提高Redis查询的速度

原文:Redis进阶实践之十八 使用管道模式提高Redis查询的速度 一.引言 学习redis 也有一段时间了,该接触的也差不多了.后来有一天,以为同事问我,如何向redis中批量的增加数据,肯定是大批量的,为了这主题,我从新找起了解决方案.目前的解决方案大都是从官网上查找和翻译的,每个实例也都调试了,正确无误.把结果告诉我同事的时候,我也跟清楚这个主题如何操作了,里面的细节也更清楚了.大然也有人说可以通过脚本来做这个操作,没错,但是我对脚本语言还没有研究很透,就不来班门弄斧了. 二.管道的由来

Python3快速入门(十八)——PyInstaller打包发布

Python3快速入门(十八)--PyInstaller打包发布 一.PyInstaller简介 1.PyInstaller简介 PyInstaller是一个跨平台的Python应用打包工具,支持 Windows/Linux/MacOS三大主流平台,能够把 Python 脚本及其所在的 Python 解释器打包成可执行文件,从而允许最终用户在无需安装 Python 的情况下执行应用程序.PyInstaller 制作出来的执行文件并不是跨平台的,如果需要为不同平台打包,就要在相应平台上运行PyIn

Python十大经典排序算法

现在很多的事情都可以用算法来解决,在编程上,算法有着很重要的地位,将算法用函数封装起来,使程序能更好的调用,不需要反复编写. Python十大经典算法: 一.插入排序 1.算法思想 从第二个元素开始和前面的元素进行比较,如果前面的元素比当前元素大,则将前面元素 后移,当前元素依次往前,直到找到比它小或等于它的元素插入在其后面, 然后选择第三个元素,重复上述操作,进行插入,依次选择到最后一个元素,插入后即完成所有排序. 2.代码实现 1 def insertion_sort(arr): 2 #插入

妙哉,十八岁!

18,一个属于青春的数字,一个人生的新起点. 依稀记得2013年的夏天,你们刚踏入二中的样子,你们的朝气和活力让百十年的二中充满勃勃生机.作为校长,非常有幸见证了你们的青春,也非常高兴分享了你们的活力.你们用诗歌向青春举杯,你们用话剧向艺术致敬,你们在运动跑道上刷新纪录,你们在学科竞赛场上创造新的辉煌……这一切都让我看到2016届的你们身上已真正熔铸了二中人的精神与气质.滴水涌泉,赤子钟鸣,每一次的相逢总见二中人内心的澎湃:六和塔影,钱塘潮涌,一次次的回眸更增二中人壮阔的心志. 十八而至,责任以