python面向对象(基础)
一 面向对象介绍
面向过程:
核心是:“过程”二字
过程的终极奥义就是将程序流程化
过程是“流水化”,用来分步骤解决问题的
面向对象:
核心是“对象”二字
对象的终极奥义就是将程序“整合”
对象是“容器”,用来盛放数据与功能的
类也是“容器”,该容器用来存放同类对象共有的数据与功能
python这门语言到底提供了什么语法来允许我们将数据与功能很好地整合到一起
程序=数据+功能
学生的容器=学生的数据+学生的功能
课程的容器=课程的数据+课程的功能
1、编程范式/思想
面向过程
介绍:
核心是“过程”二字
过程就是“流水化"
过程终极奥义是将程序流程化 优点:
1、将程序流程化,进而程序的设计会变得简单化 缺点:
1、可扩展性差 面向对象
介绍:
核心是“对象”二字
对象就是“容器",用来盛放数据与功能
对象终极奥义是将程序进行高度整合 优点:
1、提升程序的解耦合程度,进而增强程序的可扩展性 缺点:
1、设计复杂 2、面向对象编程
一:现实生活中:
1)先找出现实生活中的对象
2)然后总结归纳出现实生活中的类 二:程序中:
1)先定义程序中的类
2)后调用类产生程序中的对象(调用类的过程又称之为实例化)
二 什么是面向对象的程序设计及为什么要有它
面向过程的程序设计:核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么......面向过程的设计就好比精心设计好一条流水线,是一种机械式的思维方式。
优点是:复杂度的问题流程化,进而简单化(一个复杂的问题,分成一个个小的步骤去实现,实现小的步骤将会非常简单)
缺点是:一套流水线或者流程就是用来解决一个问题,生产汽水的流水线无法生产汽车,即便是能,也得是大改,改一个组件,牵一发而动全身。
应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。
面向对象的程序设计:核心是对象二字,(要理解对象为何物,必须把自己当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也可以创造出来。面向对象的程序设计好比如来设计西游记,如来要解决的问题是把经书传给东土大唐,如来想了想解决这个问题需要四个人:唐僧,沙和尚,猪八戒,孙悟空,每个人都有各自的特征和技能(这就是对象的概念,特征和技能分别对应对象的数据属性和方法属性),然而这并不好玩,于是如来又安排了一群妖魔鬼怪,为了防止师徒四人在取经路上被搞死,又安排了一群神仙保驾护航,这些都是对象。然后取经开始,师徒四人与妖魔鬼怪神仙交互着直到最后取得真经。如来根本不会管师徒四人按照什么流程去取),对象是特征与技能的结合体,基于面向对象设计程序就好比在创造一个世界,你就是这个世界的上帝,存在的皆为对象,不存在的也可以创造出来,与面向过程机械式的思维方式形成鲜明对比,面向对象更加注重对现实世界的模拟,是一种“上帝式”的思维方式。
优点是:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。
缺点:
1. 编程的复杂度远高于面向过程,不了解面向对象而立即上手基于它设计程序,极容易出现过度设计的问题。一些扩展性要求低的场景使用面向对象会徒增编程难度,比如管理linux系统的shell脚本就不适合用面向对象去设计,面向过程反而更加适合。
2. 无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即便是上帝也无法准确地预测最终结果。于是我们经常看到对战类游戏,新增一个游戏人物,在对战的过程中极容易出现阴霸的技能,一刀砍死3个人,这种情况是无法准确预知的,只有对象之间交互才能准确地知道最终的结果。
应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方
面向对象的程序设计并不是全部。对于一个软件质量来说,面向对象的程序设计只是用来解决扩展性。

三 实现面向对象编程
# 一、先定义类
# 类是对象相似数据与功能的集合体
# 所以类中最常见的是变量与函数的定义,但是类体其实是可以包含任意其他代码的
# 注意:类体代码是在类定义阶段就会立即执行,会产生类的名称空间
# 类的命名应该使用“驼峰体”
class Student:
# 1、变量的定义
school = '清华大学' # 数据 # 2、功能的定义
def tell_stu_info(stu_obj):
print('学生信息:名字:{} 年龄:{} 性别:{}'.format(
stu_obj['stu_name'],
stu_obj['stu_age'],
stu_obj['stu_gender'],
)) def set_info(stu_obj, x, y, z):
stu_obj['stu_name'] = x
stu_obj['stu_age'] = y
stu_obj['stu_gender'] = z # print('---->') # 类的定义阶段,就会立即执行 print(Student.__dict__)
print(Student.__dict__['school'])
# 属性访问的语法
# 1、访问数据属性
print(Student.school) # 等同于Student.__dict__['school']
# 2、访问函数属性
print(Student.set_info) # 等同于Student.__dict__['set_info'] # 二、再调用类产生对象
# 产生对象名称空间,并与类名称空间产生关联
Stu1_obj = Student()
Stu2_obj = Student()
Stu3_obj = Student() print(Stu1_obj.__dict__)
print(Stu2_obj.__dict__)
print(Stu2_obj.__dict__) # 对象定制自己独有的属性
# 问题1:代码重复
# 问题2:属性的查找顺序
Stu1_obj.stu_name = 'lq' # Stu1_obj.__dict__['stu_name']='lq'
Stu1_obj.stu_age = 18 # Stu1_obj.__dict__['stu_age']=18
Stu1_obj.stu_gender = 'female' # Stu1_obj.__dict__['stu_gender']='female'
print(Stu1_obj.__dict__) Stu2_obj.stu_name = 'zd'
Stu2_obj.stu_age = 19
Stu2_obj.stu_gender = 'male'
print(Stu2_obj.__dict__) Stu3_obj.stu_name = 'xiaobao'
Stu3_obj.stu_age = 5
Stu3_obj.stu_gender = 'female'
print(Stu3_obj.__dict__) # 解决问题:
# 解决方案一:
def init(obj, x, y, z):
obj.stu_name = x
obj.stu_age = y
obj.stu_gender = z init(Stu1_obj, 'lq', 18, 'male')
print(Stu1_obj.__dict__) # 解决方案二:
# 一:先定义类
class Student: # 类的命名应该使用“驼峰体”
# 1、变量的定义
school = '清华大学' # 数据 # 空对象,'egon',18,'male'
def __init__(obj, x, y, z):
obj.stu_name = x # 空对象.stu_name='egon'
obj.stu_age = y # 空对象.stu_age=18
obj.stu_gender = z # 空对象.stu_gender='male' # 2、功能的定义
def tell_stu_info(stu_obj):
print('学生信息:名字:{} 年龄:{} 性别:{}'.format(
stu_obj['stu_name'],
stu_obj['stu_age'],
stu_obj['stu_gender'],
)) def set_info(stu_obj, x, y, z):
stu_obj['stu_name'] = x
stu_obj['stu_age'] = y
stu_obj['stu_gender'] = z # 二:再调用类产生对象
# 调用类的过程又称之为实例化,发生了三件事
# 1、先产生一个空对象
# 2、python会自动调用类中的__init__方法,然后将空对象已经调用类是括号内传入的参数一同传给__init__方法
# 3、返回初始完的对象 Stu1_obj = Student('lq', 19, 'male')
Stu2_obj = Student('zd', 19, 'male')
Stu3_obj = Student('xiaobao', 18, 'male') print(Stu1_obj.__dict__)
print(Stu2_obj.__dict__)
print(Stu3_obj.__dict__) # 总结__init__方法
# 1、会在调用类时自动触发执行,用来为对象初始化自己独有的数据
# 2、__init__内应该存放是为对象初始化属性的功能,但是可以存放任意其他代码,想要在
# 类调用时就立刻执行的代码都可以放到该方法内
# 3、__init__方法必须返回None
四 属性查找

先查找对象名称空间中查找数据属性,找不到,再到类的名称空间里找
class Student: # 类的命名应该使用“驼峰体”
# 1、变量的定义
school = '清华大学' # 数据
count = 0 def __init__(self, x, y, z):
Student.count += 1 # 实例化计数
self.stu_name = x # 空对象.stu_name='egon'
self.stu_age = y # 空对象.stu_age=18
self.stu_gender = z # 空对象.stu_gender='male' # 2、功能的定义
def tell_stu_info(obj):
print('学生信息:名字:{} 年龄:{} 性别:{}'.format(
obj.stu_name,
obj.stu_age,
obj.stu_gender,
)) def set_info(obj, x, y, z):
obj.stu_name = x
obj.stu_age = y
obj.stu_gender = z Stu1_obj = Student('lq', 19, 'male')
Stu2_obj = Student('zd', 19, 'male')
Stu3_obj = Student('xiaobao', 18, 'male') # 类中存放的是对象共有的数据与功能
# 一、类可以访问:
# 1、类的数据属性
print(Student.school)
# 2、类的函数属性
print(Student.set_info)
print(Student.tell_stu_info)
# 二、但其实类中的东西是给对象用的
# 1、类的数据属性是共享给所有对象用的,大家访问的地址都一样
print(Student.school)
print(Stu1_obj.school)
print(Stu2_obj.school)
print(Stu3_obj.school)
Stu1_obj.school = '上海中学' # 对象Stu1,自己名称空间里建school数据属性
print(Stu1_obj.school) # 2、类中定义的函数主要是给对象使用的,而且是绑定给对象的,虽然所有对象指向的都是相同的功能,
# 但是绑定到不同的对象就是不同的绑定方法,内存地址各不相同 # 类调用自己的函数属性必须严格按照函数的用法来
Student.tell_stu_info(Stu1_obj)
Student.tell_stu_info(Stu2_obj)
Student.tell_stu_info(Stu3_obj)
Student.set_info(Stu1_obj, 'LQ', 33, 'MALL')
Student.set_info(Stu2_obj, 'ZD', 33, 'MALL')
Student.set_info(Stu3_obj, 'XIAOBAO', 6, 'MALL')
'''
学生信息:名字:lq 年龄:19 性别:male
学生信息:名字:zd 年龄:19 性别:male
学生信息:名字:xiaobao 年龄:18 性别:male
学生信息:名字:LQ 年龄:33 性别:MALL
学生信息:名字:ZD 年龄:33 性别:MALL
学生信息:名字:XIAOBAO 年龄:6 性别:MALL
''' # 绑定方法的特殊之处在于:谁来调用绑定方法就会将谁当做第一个参数自动传入,
# 所以类中定义的函数第一个参数默认self,类中函数方法(无参函数,也需要有self的原因)
print(Student.tell_stu_info)
print(Stu1_obj.tell_stu_info) # 绑定方法,
print(Stu2_obj.tell_stu_info)
print(Stu3_obj.tell_stu_info)
'''
<function Student.tell_stu_info at 0x000001D76D422550>
<bound method Student.tell_stu_info of <__main__.Student object at 0x000001D76D3C30A0>>
<bound method Student.tell_stu_info of <__main__.Student object at 0x000001D76D3C3310>>
<bound method Student.tell_stu_info of <__main__.Student object at 0x000001D76D3C9550>>
''' # 直接对象来调用函数方法,对象直接当第一个参数自动传入,不用再像类调用函数方法时,传对象参数
# 比从类中调用,更简单,并且语意明确
Stu1_obj.tell_stu_info()
Stu2_obj.tell_stu_info()
Stu3_obj.tell_stu_info()
Stu1_obj.set_info('LQ', 33, 'MALL')
Stu2_obj.set_info('ZD', 33, 'MALL')
Stu3_obj.set_info('XIAOBAO', 6, 'MALL')
'''
学生信息:名字:lq 年龄:19 性别:male
学生信息:名字:zd 年龄:19 性别:male
学生信息:名字:xiaobao 年龄:18 性别:male
学生信息:名字:LQ 年龄:33 性别:MALL
学生信息:名字:ZD 年龄:33 性别:MALL
学生信息:名字:XIAOBAO 年龄:6 性别:MALL
''' # Python中一切皆为对象,且Python3中类与类型是一个概念
# 在上述介绍类与对象的使用过程中,我们更多的是站在底层原理的角度去介绍类与对象之间的关联关系,
# 如果只是站在使用的角度,我们无需考虑语法“对象.属性
# "中”属性“到底源自于哪里,只需要知道是通过对象获取到的就可以了,所以说,对象是一个高度整合的产物,
# 有了对象,我们只需要使用“对象.xxx”的语法就可以得到跟这个对象相关的所有数据与功能,十分方便且解耦合程度极高。
五 练习
对象可以当参数传递
# 整合---》解耦合---》扩展性增强 # 学校
class School:
school_name = 'OLDBOY' def __init__(self, nickname, addr):
self.nickname = nickname
self.addr = addr
self.classes = [] def related_class(self, grade_obj): # 传对象,在.'属性'
self.classes.append(grade_obj) # 列表存储的班级对象
# self.classes.append(班级名称) def class_tell_info(self):
print(self.nickname)
for grade_obj in self.classes:
grade_obj.tell_course() # 1、学校
# 1)创建校区
school_obj1 = School('上海校区', '上海')
school_obj2 = School('北京校区', '北京') # 2)为学校开设班级
# school_obj1.related_class('脱产14期')
# school_obj1.related_class('脱产15期')
# school_obj2.related_class('脱产29期') # 3)查看每个校区开设的班级
# school_obj1.class_tell_info() # 班级
class Grade:
def __init__(self, name):
self.name = name
self.course = None def related_course(self, course_obj):
self.course = course_obj # 变量名有,就是修改,没有,就是新建 def tell_course(self):
print('班级名:{}'.format(self.name),end=' ')
self.course.tell_info() # 2、班级
# 1)创建班级
grade_obj1 = Grade('脱产14期')
grade_obj2 = Grade('脱产15期')
grade_obj3 = Grade('脱产29期') # 2)为班级关联一个课程
# grade_obj1.related_course('python全栈开发')
# grade_obj2.related_course('linux运维')
# grade_obj3.related_course('python全栈开发') # 3)查看班级开设的课程信息
# grade_obj1.tell_course()
# grade_obj2.tell_course()
# grade_obj3.tell_course() # 4) 为学校开设办班级
# 上海校区开了:脱产14期,上海校区开了脱产15期
school_obj1.related_class(grade_obj1)
school_obj1.related_class(grade_obj2) # print(school_obj1.classes) # 课程列表里,是对象 # 北京校区开了:脱产29期
school_obj2.related_class(grade_obj3) # school_obj1.class_tell_info() # 课程
class Course:
def __init__(self, name, period, price):
self.name = name
self.period = period
self.price = price def tell_info(self):
print('<课程名:{},课程周期:{},课程价格{}>'.format(self.name, self.period, self.price)) # 1)创建课程
course_obj1 = Course('python全栈开发', '6个月', 20000)
course_obj2 = Course('linux运维', '5个月', 18000) # 2) 查看课程的详细信息
# course_obj1.tell_info()
# course_obj2.tell_info() # 3) 为班级关联课程对象
grade_obj1.related_course(course_obj1)
grade_obj2.related_course(course_obj2)
grade_obj3.related_course(course_obj1) # grade_obj1.tell_course()
# grade_obj2.tell_course()
# grade_obj3.tell_course() school_obj1.class_tell_info()
school_obj2.class_tell_info() class Student:
pass
python面向对象(基础)的更多相关文章
- Python 面向对象 基础
编程范式概述:面向过程 和 面向对象 以及函数式编程 面向过程:(Procedure Oriented)是一种以事件为中心的编程思想. 就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现 ...
- python面向对象基础
面向对象基础 1. 简述 编程方式: 面向过程: 根据代码在脚本的堆叠顺序,从上到下依次执行 函数式编程:将相同功能的代码封装到函数中,直接调用即可,减少代码重复性 面向对象:对函数进行分类和封装,将 ...
- Python 面向对象基础知识
面向对象基础知识 1.什么是面向对象编程? - 以前使用函数 - 类 + 对象 2.什么是类什么是对象,又有什么关系? class 类: def 函数1(): pass def 函数2(): pass ...
- python 面向对象基础和高级复习
面向对象基础 面向对象编程 面向过程编程:类似于工厂的流水线 优点:逻辑清晰 缺点:扩展性差 面向对象编程:核心是对象二字,对象属性和方法的集合体,面向对象编程就是一堆对象交互 优点:扩展性强 缺点: ...
- 十六、python面向对象基础篇
面向对象基础: 在了解面向对象之前,先了解下变成范式: 编程范式是一类典型的编程风格,是一种方法学 编程范式决定了程序员对程序执行的看法 oop中,程序是一系列对象的相互作用 python支持多种编程 ...
- 1.Python面向对象基础
面向对象(OOP) 面向对象编程--object oriented programming 简写 OOP 面向过程和面向对象的区别: 面向过程: 1.把完成某一个需求的所有步骤从头到尾逐步实现 2 ...
- [python面向对象]--基础篇
1.#类 #类就是一个模板,模板里可以包含多个函数,函数里实现一些功能 #定义一个类 class bar: def foo(self,agr): print(self,agr) obj = bar() ...
- Python面向对象基础:编码细节和注意事项
在前面,我用了3篇文章解释python的面向对象: 面向对象:从代码复用开始 面向对象:设置对象属性 类和对象的名称空间 本篇是第4篇,用一个完整的示例来解释面向对象的一些细节. 例子的模型是父类Em ...
- Python面向对象基础一
公司可能过一两个月就要从深圳搬到东莞松山湖,项目组的现在有的在转Java或其他语言的,问我们要不要转java+hoodap+spark方向,我还是先不转,毕竟之前是从ios转回C#,这现在在转其他的那 ...
- python面向对象基础-01
面向对象(OOP)基本概念 前言 话说三国时期曹军于官渡大败袁绍,酒席之间,曹操诗兴大发,吟道:喝酒唱歌,人生真爽! 众将直呼:"丞相好诗",于是命印刷工匠刻板印刷以流传天下; 待 ...
随机推荐
- Flink-postgres-cdc实时同步报错:无法访问文件 "decoderbufs": 没有那个文件或目录
问题描述 Caused by: org.postgresql.util.PSQLException: 错误: 无法访问文件 "decoderbufs": 没有那个文件或目录 解决办 ...
- [Java]《On Java》阅读记录之 -- 可变参数重载问题
<On Java>阅读记录之 -- 可变参数重载问题 有下面一段代码: public class OverloadingVarargs2 { static void f(float i , ...
- JS leetcode 存在重复元素 II 题解分析,记一次震惊的负向优化
壹 ❀ 引 整理下今天做的算法题,题目难度不高,但在优化角度也是费了一些功夫.题目来自219. 存在重复元素 II,问题描述如下: 给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i ...
- 端口碰撞Port Knocking和单数据包授权SPA
端口碰撞技术 Port knocking 从网络安全的角度,服务器开启的端口越多就越不安全,因此系统安全加固服务中最常用的方式,就是先关闭无用端口,再对提供服务的端口做访问控制.而作为远程管理与维护的 ...
- windbg 分析 32 位进程的 64 位转储文件
场景: x86 的项目在 x64 的 windows 机器上运行时出现未响应的情况,使用任务管理器创建该进程的转储文件 因为项目是 32 位的,所以使用 x86 的 windbg 来调试 dmp 文件 ...
- C++检测句柄的权限
主要是依靠NtQueryObject函数,其中需要传入ObjectBasicInformation参数 PUBLIC_OBJECT_BASIC_INFORMATION结构包含可用于对象的全部信息的子集 ...
- lock锁,Semaphore信号量,Event事件,进程队列Queue,生产者消费者模型,JoinableQueue---day31
1.lock锁 # ### 锁 lock from multiprocessing import Process,Lock import json,time # (1) lock的基本语法 " ...
- 【图论#02】岛屿系列题(数量、周长、最大面积),flood fill算法的代码实现与优化
岛屿数量 给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量. 岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成. 此外,你可以假设该网 ...
- 【LeetCode链表#7】设计一个链表并实现常见的操作方法
设计链表 题目 力扣题目链接 设计链表的实现.您可以选择使用单链表或双链表.单链表中的节点应该具有两个属性:val 和 next.val 是当前节点的值,next 是指向下一个节点的指针/引用.如果要 ...
- SUB-LVDS 与LVDS 互联
SUB-LVDS 与 LVDS介绍 电气规范 今天有同学问SUB-LVDS输出是否能接到LVDS输入上,以前没用过SUB-LVDS,一起学习一下. Sub-LVDS is a differential ...