Python全栈开发之路 【第七篇】:面向对象编程设计与开发(1)

时间:2023-01-12 04:44:31

本节内容

一、编程范式

编程指的是写程序、敲代码,就是指程序员用特定的语法、数据结构和算法编写的代码,目的是来告诉计算机如何执行任务的。

在编程的世界里最常见的两大流派是:面向过程与面向对象。“功夫的流派没有高低之分,只有习武的人才有高低之分“,在编程世界里更是这样,面向过程与面向对象在不同的场景下都各有优劣,谁好谁坏不能一概而论。

二、面向过程的程序设计

核心是“过程”二字,“过程”指的是解决问题的步骤,即先干什么再干什么......,基于面向过程设计程序就好比在设计一条流水线,是一种机械式的思维方式。

优点:复杂问题简单化。

# 写一个数据远程备份程序,
#分三步,本地数据打包,上传至云服务器,测试备份文件可用性
import os def data_backup(folder):
print("找到备份目录: %s" %folder)
print('正在备份......')
zip_file='/tmp/backup20181103.zip'
print('备份成功,备份文件为: %s' %zip_file)
return zip_file def cloud_upload(file):
print("\nconnecting cloud storage center...")
print("cloud storage connected.")
print("upload file...%s...to cloud..." %file)
link='http://www.xxx.com/bak/%s' %os.path.basename(file)
print('close connection.....')
return link def data_backup_test(link):
print("\n下载文件: %s , 验证文件是否无损" %link) def main():
#步骤一:本地数据打包
zip_file = data_backup("c:\\users\\alex\欧美100G高清无码") #步骤二:上传至云服务器
link=cloud_upload(zip_file) #步骤三:测试备份文件的可用性
data_backup_test(link) if __name__ == '__main__':
main()

面向过程的例子

缺点:扩展性极差。

应用场景:

  面向过程的程序设计思想一般用于那些功能一旦实现之后就很少需要改变的场景, 如果你只是写一些简单的脚本,去做一些一次性任务,用面向过程的方式是极好的,著名的例子有Linux內核,git,以及Apache HTTP Server等。但如果你要处理的任务是复杂的,且需要不断迭代和维护 的, 那还是用面向对象最方便了。

三、面向对象的程序设计

核心是“对象”二字,要理解对象为何物,必须把自己当成上帝,在上帝眼里,世间存在的万物皆为对象,不存在的也可以创造出来,与面向过程机械式的思维方式形成鲜明对比,面向对象更加注重对现实世界而非流程的模拟,是一种“上帝式”的思维方式。

优点:可扩展性高。

缺点:编程的复杂度远高于面向过程。

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

四、类与对象

对象是特征与技能的结合体,而类是一系列对象相似的特征与技能的结合体。

在现实世界中:肯定是先有对象,再有类;

在程序中:要先定义 类,后产生对象。

定义类

按照上述步骤,我们来定义一个类(我们站在学校的角度去看,在座的各位都是学生)

>>>在现实世界中,先有对象,再有类

对象1:李坦克
特征:
学校=实中
姓名=李坦克
性别=男
年龄=18
技能:
学习
吃饭
睡觉 对象2:王大炮
特征:
学校=实中
姓名=王大炮
性别=女
年龄=38
技能:
学习
吃饭
睡觉 对象3:牛榴弹
特征:
学校=实中
姓名=牛榴弹
性别=男
年龄=78
技能:
学习
吃饭
睡觉 现实中的实中的学生类
相似的特征:
学校=实中
相似的技能:
学习
吃饭
睡觉

>>>在程序中,务必保证:先定义(类),后使用类(用来产生对象)

#在Python中程序中的类用class关键字定义,而在程序中特征用变量标识,技能用函数标识,因而类中最常见的无非是:变量和函数的定义
class SchoolStudent:
school='实中'
def learn(self):
print('is learning') def eat(self):
print('is eating') def sleep(self):
print('is sleeping')

注意:

①类中可以有任意的python代码,这些代码在类的定义阶段就会执行,因而会产生新的名称空间,用来存放类的变量名与函数名,通过SchoolStudent.__dict__ 就可以查看。

②类中定义的名字,都是类的属性,点是访问类属性的语法。

类的使用

类属性的 增 删 改 查

SchoolStudent.school #查
SchoolStudent.school='University' #改
SchoolStudent.x=1 #增
del SchoolStudent.x #删

调用类,也成为实例化,得到程序中的对象

s1=SchoolStudent()
s2=SchoolStudent()
s3=SchoolStudent() #如此,s1、s2、s3都一样了,而这三者除了相似的属性之外还各种不同的属性,这就用到了__init__

__init__ 方法

#注意:该方法是在对象产生之后才会执行,只用来为对象进行初始化操作,可以有任意代码,但一定不能有返回值
# __init__ 方法用来为对象定制对象独有的特征
class LuffyStudents:
school = 'luffycity' # 上下对应 stu1, 'hyp', 22, 'man'
def __init__(self, name, age, sex):
self.Name = name
self.Age = age
self.Sex = sex # 相当于
#stu1.Name = 'hyp'
#stu1.Age = 22
#stu1.Sex = 'man' def learn(self):
print(' is learning') def eating(self):
print(' is eating') # 后产生对象
stu1 = LuffyStudents('hyp', 22, 'man') print(stu1) """
加上__init__ 方法后,实例化的步骤:
1.先产生一个空对象 stu1
2.LuffyStudents.__init__(stu1, 'hyp', 22, 'man')
print(LuffyStudents.__init__) --> 返回的是 类的函数属性
""" # # 查
# print(stu1.__dict__)
# print(stu1.Name)
#
# # 改
# stu1.Name = 'lcy'
# print(stu1.__dict__)
# print(stu1.Name)
#
# # 删除
# del stu1.Name
# print(stu1.__dict__)
#
# # 增加
# stu1.class_name = '全栈开发'
# print(stu1.__dict__) """
# --> 先产生空对象,然后再调__init__,
并传参数 LuffyStudents.__init__(stu2,'lcy', 22, '女')
"""
stu2=LuffyStudents('lcy', 22, '女')

对象的使用

#执行__init__,s1.name='牛榴弹',很明显也会产生对象的名称空间可以用s2.__dict__查看,查看结果为
{'name': '王大炮', 'age': '女', 'sex': 38} s2.name #查,等同于s2.__dict__['name']
s2.name='王三炮' #改,等同于s2.__dict__['name']='王三炮'
s2.course='python' #增,等同于s2.__dict__['course']='python'
del s2.course #删,等同于s2.__dict__.pop('course')

补充:

①站的角度不同,定义出的类是截然不同的;

②现实中的类并不完全等于程序中的类,比如现实中的公司类,在程序中有时需要拆分成部门类,业务类等;

③有时为了编程需求,程序中也可能会定义现实中不存在的类,比如策略类,现实中并不存在,但是在程序中却是一个很常见的类。

五、类的属性查找与绑定方法

类的属性:

  分为  数据属性 和 函数属性。

1、类 的 数据属性 是所有对象共有的,指向的是 同一个内存地址。

#类的数据属性是所有对象共享的,id都一样
print(id(SchoolStudent.school)) print(id(s1.school)) #4377347328
print(id(s2.school)) #4377347328
print(id(s3.school)) #4377347328

2、类的函数属性 是绑定给 对象 用的,称为绑定到对象的方法

#类的函数属性是绑定给对象使用的,obj.method称为绑定方法,内存地址都不一样

print(SchoolStudent.learn) #<function SchoolStudent.learn at 0x1021329d8>

print(s1.learn)# 结果:<bound method SchoolStudent.learn of #<__main__.SchoolStudentobject at 0x1021466d8>>

print(s2.learn) # 结果:<bound method SchoolStudent.learn of <__main__.SchoolStudentobject at 0x102146710>>

print(s3.learn) # 结果:<bound method SchoolStudent.learn of <__main__.SchoolStudentobject at 0x102146748>>

#ps:id是python的实现机制,并不能真实反映内存地址,如果有内存地址,还是以内存地址为准

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

绑定方法

先定义 类 并实例化出三个对象

class SchoolStudent:
school='实中'
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def learn(self):
print('%s is learning' %self.name) #新增self.name def eat(self):
print('%s is eating' %self.name) def sleep(self):
print('%s is sleeping' %self.name) s1=SchoolStudent('李坦克','男',18)
s2=SchoolStudent('王大炮','女',38)
s3=SchoolStudent('牛榴弹','男',78)

类中定义的函数(没有被任何装饰器修饰的)是类的函数属性,类可以使用,但必须遵循函数的参数规则,有几个参数就要传几个参数。

SchoolStudent.learn(s1) #李坦克 is learning
SchoolStudent.learn(s2) #王大炮 is learning
SchoolStudent.learn(s3) #牛榴弹 is learning s1.learn() #等同于SchoolStudent.learn(s1)
s2.learn() #等同于SchoolStudent.learn(s2)
s3.learn() #等同于SchoolStudent.learn(s3)

类中定义的函数(没有被任何装饰器装饰的),其实主要是给对象使用的,而且是绑定到对象的,虽然所有对象指向的都是相同的功能,但是绑定到不同的对象就是不同的绑定方法。

强调:

  ①绑定到对象的方法的特殊之处在于,绑定给谁就由谁来调用,谁来调用,就会将‘谁’本身当做第一个参数传给方法,即自动传值(方法__init__也是一样的道理)

  绑定到对象的方法的这种自动传值的特征,决定了在类中定义的函数都要默认写一个参数self,self可以是任意名字,但是约定俗成地写出self。

类即类型

python 中 一切皆对象,且python3 中 类与类型是一个概念,类型就是类 。

#类型dict就是类dict
>>> list
<class 'list'> #实例化的到3个对象l1,l2,l3
>>> l1=list()
>>> l2=list()
>>> l3=list() #三个对象都有绑定方法append,是相同的功能,但内存地址不同
>>> l1.append
<built-in method append of list object at 0x10b482b48>
>>> l2.append
<built-in method append of list object at 0x10b482b88>
>>> l3.append
<built-in method append of list object at 0x10b482bc8> #操作绑定方法l1.append(3),就是在往l1添加3,绝对不会将3添加到l2或l3
>>> l1.append(3)
>>> l1
[3]
>>> l2
[]
>>> l3
[]
#调用类list.append(l3,111)等同于l3.append(111)
>>> list.append(l3,111) #l3.append(111)
>>> l3
[111]
"""
练习一:编写一个学生类,产生一堆学生对象,
要求:
有一个计数器(属性),统计总共实例了多少个对象 """ class Student:
school = 'luffycity' # 数据 属性
count = 0
def __init__(self, name, age, sex): # 类 属性
# self.count += 1
self.name = name
self.age = age
self.sex = sex
Student.count += 1 # 实现共有的属性 累加
# 有几个实例化对象,就会累加几次 def learn(self): # 函数 属性
print('%s is learning ' %self.name) # 实例化出三个对象
stu1 = Student('hyp', 'male', 18)
stu2 = Student('lcy', 'female', 17)
stu3 = Student('alex', 'male', 28) # 只把计数的方法,反映给了 每个对象 独有的特征,不能实现累加
print(stu1.count)
print(stu2.count)
print(stu3.count)
print(stu1.__dict__)
print(stu2.__dict__)
print(stu3.__dict__)
#
print(Student.count) """练习题二:模仿王者荣耀定义两个英雄类
要求:
英雄需要有 昵称、攻击力、生命值 等属性;
实例化出两个英雄对象;
英雄之间可以互殴,被殴打的一方掉血,血量小于0则判定为死亡。
""" class Geren:
camp = 'Demacia' def __init__(self, nickname, life_value, aggersivity):
self.nickname = nickname
self.life_value = life_value
self.aggersivity = aggersivity def attack(self, enemy):
enemy.life_value -= self.aggersivity class Riven:
camp = 'Demacia' def __init__(self, nickname, life_value, aggersivity):
self.nickname = nickname
self.life_value = life_value
self.aggersivity = aggersivity def attack(self, enemy):
enemy.life_value -= self.aggersivity g1 = Geren('草丛伦', 100, 30)
r1 = Riven('锐雯',80,50) g1.attack(r1)

小练习

Python全栈开发之路 【第七篇】:面向对象编程设计与开发(1)的更多相关文章

  1. 战争热诚的python全栈开发之路

    从学习python开始,一直是自己摸索,但是时间不等人啊,所以自己为了节省时间,决定报个班系统学习,下面整理的文章都是自己学习后,认为重要的需要弄懂的知识点,做出链接,一方面是为了自己找的话方便,一方 ...

  2. python面向对象编程设计与开发

    一.什么是面向对象的程序设计 1.何为数据结构? 数据结构是指相互之间存在一种或多种特定关系的数据元素的集合,如列表.字典. 2.何为编程? 编程是指程序员用特定的语法+数据结构+算法,组成的代码,告 ...

  3. Python全栈开发之路 【第八篇】:面向对象编程设计与开发(2)

    一.继承与派生 什么是继承? 继承指的是类与类之间的关系,是一种什么是什么的关系,继承的功能之一就是用来解决代码重用问题. 继承是一种创建新的类的方式,在python中,新建的类可以继承一个或多个父类 ...

  4. python全栈开发之路

    一.Python基础 python简介 python数据类型(数字\字符串\列表) python数据类型(元组\字典) python数据类型(集合) python占位符%s,%d,%r,%f prin ...

  5. 全栈JavaScript之路(七)学习 Comment 类型节点&period;

    凝视 在DOM中,用 Comment 类型 节点表示, 构造器函数为:  function Comment(){[native code]}. comment 节点的特征: nodeType:8 no ...

  6. python学习之老男孩python全栈第九期&lowbar;day022知识点总结——初识面向对象

    一. 面向对象的引入# 人狗大战 def person(name,HP,aggr,sex): person = { 'name':name, # 昵称 'HP':HP, # 生命值 'aggr':ag ...

  7. 20180315-Python面向对象编程设计和开发

    1.在子类中调用父类的方法 在子类派生出的新方法中,往往需要重用父类的方法,我们有两种实现方式: 方式一:父类名.父类方法() Animal.__init__(self,name) 方式二:super ...

  8. 《Python全栈开发指南》第3版 Alex著(LFXC2018)

    第一章 Python基础——Python介绍&循环语句 1.1 编程语言介绍 1.2 Python介绍 1.3 Python安装 1.4 第一个Python程序 1.5 变量 1.6 程序交互 ...

  9. python 全栈开发之路 day1

    python 全栈开发之路 day1   本节内容 计算机发展介绍 计算机硬件组成 计算机基本原理 计算机 计算机(computer)俗称电脑,是一种用于高速计算的电子计算机器,可以进行数值计算,又可 ...

随机推荐

  1. Razor基础语法一

    目录: 什么是Razor? 渲染HTML Razor语法 隐式 Razor 表达式 显式 Razor 表达式 什么是Razor? Razor是基于服务端代码转换成网页的标记语法.语法主要包括Razor ...

  2. lzo压缩格式文件查看

    使用lzop命令解压并查看 :lzop -cd xxx.lzo |more 附压缩命令:lzop xxx.log (生成xxx.log.lzo) 其它参数: # lzop -v test # 创建te ...

  3. Beta版本冲刺前准备

    Beta版本冲刺 经过紧张的Alpha阶段,很多组已经从完全不熟悉语言和环境,到现在能够实现初步的功能.下一阶段即将加快编码进度,完成系统功能.强化软件工程的体会. 1.凡事预则立,在Beta开始前, ...

  4. NGUI的新手引导的实现

    先声明一下,UNITY新手,如果说的有不对的地方,欢迎各位大神指正. 最近在项目需要实现新手引导,最基础的需求就是需要一个带黑色遮罩的引导UI,类似下图这种: 对,就是这么敷衍的UI,因为是我随手做的 ...

  5. 定位属性position

    定位属性position小结 1.元素为fixed(固定的),则是固定定位,即使是子元素,也不参考父元素的位置,即以浏览器作为参考定位.相当于电脑屏幕的一只蚂蚁,你无论怎么滑动屏幕,还是在原来的位置. ...

  6. HoloLens开发手记 - HoloLens真机上手简评

    千呼万唤始出来,终于今天拿到了HoloLens真机. 使用体验 使用自带的应用录制了一段使用视频,如下 设备概览 包装盒 本体 试戴 实际效果 GalaxyExplorer试玩 全息图像贴到现实场景表 ...

  7. 本地电脑无法连接到MySQL

    问题描述: ERROR 1130 (HY000): Host 'localhost' is not allowed to connect to this MySQL server 首先网上的问题大部分 ...

  8. input框的输入限制

    1.输入数字 <input onKeyUp="value=value.replace(/[^\d|chun]/g,'')"> 2.只输入中文 <input typ ...

  9. 使用Python编写简单网络爬虫抓取视频下载资源

    我第一次接触爬虫这东西是在今年的5月份,当时写了一个博客搜索引擎.所用到的爬虫也挺智能的,起码比电影来了这个站用到的爬虫水平高多了! 回到用Python写爬虫的话题. Python一直是我主要使用的脚 ...

  10. thinkphp使用with对关联数据进行预加载

    1.with('relation'),只预加载relation这个关联,如下面 public function relation() { return $this->hasOne(Relatio ...