Py修行路 python基础 (十四)递归 及 面向对象初识及编程思想
一、递归
1、定义:
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
(1)递归就是在过程或函数里调用自身;
(2)在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
def age(n):
if n ==1: #条件判定
return 10 #返回一个结果
else:
return age(n-1)+2 #重复调用函数本身,系统会将运算的结果存放到栈,然后再依次的进行取值调用。
print(age(5)) #打印结果
执行结果:18
2、优缺点:
递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。
递归的缺点:递归算法解题的运行效率较低。在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。
def func():
print("*******")
func()
func() #执行结果
[Previous line repeated 993 more times]
*******
File "F:/py_fullstack_s4/day26/递归.py", line 8, in func
*******
print("*******")
*******
RecursionError: maximum recursion depth exceeded while calling a Python object
3、递归编程的注意点:
1. 必须有一个明确的结束条件。
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少。
3.递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)。
4、此处引出一个新的知识点:二分法
二分法,是一种快速查找的方法,时间复杂度低,逻辑简单易懂,总的来说就是不断的除以2除以2...
他主要应用于有序序列中,原理是每次查找都将原序列折半,逐渐缩小查找范围的一种算法。应用于递归,循环之中,直到找到结果。
#运用 递归 和 二分法 的运算方式,查找列表中的某个值
data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]
num = int(input("please input your want to find number:"))
def search(num,data):
if len(data) > 1: #排除列表分割,仅剩一个元素的情况
#二分法#
a = int(len(data)//2) #将计算列表的长度,除以2 取整数
mid_value = data[a] #取当前中间的值
if num > mid_value: #要找的值 大于 中间的值
data = data[a:] #将原列表从中间值往后,取出来,构建一个新列表
search(num,data) #递归判断
elif num < mid_value: #要找的值 小于 中间的值
data = data[:a] #将原列表开始到中间值,取出来,构建一个新列表
search(num,data) #递归判断
else: #正好是这个值
print("find it!!",num)
return #打印
else: #判断列表分割,仅剩一个元素的情况
if data[0] == num:
print('find it!! %s'%data[0])
else: #列表中没有这个值
print('not this num %s'%num) search(num,data) #执行结果:
please input your want to find number:18
find it!! 18
二、函数式编程介绍
1、用def模仿数学中函数的方式,传一个值,就得一个结果。不会修改外部的状态。
2、代码非常的精简,直接导致可读性非常差。
三、面向对象的程序设计
1、前提铺垫:
python中一切皆为对象,python 3统一了类与类型的概念,类型即是类。例如:int,str,list,等等……
编程语言中,是先有了类,然后再产生一个个对象。而现实生活中正好相反。
明确一点:面向对象编程是一种编程方式,此编程方式的功能需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用。
类就是一个模板,模板里可以包含创建多个函数,函数里实现自定义的功能
对象则是根据模板创建的实例,通过实例(对象)可以执行类中定义的函数
2、语法:
1)创建类:class是关键字,表示类 class *** #创建类
2)创建对象:类名称后加括号 将结果赋给一个变量 即可 x = ***() #创建对象
class hello: #任意定义一个类
camp = 'hello world'
def f(self):
print("f")
h = hello() # 类实例化
print(h) #打印 #执行结果: <__main__.hello object at 0x00000000026C9630>
3、类与对象
1)什么是对象:
以游戏举例:英雄联盟,每个玩家选一个英雄,每个英雄都有自己的特征和和技能,特征即数据属性,技能即方法属性,特征与技能的结合体就一个对象。
2)什么是类:
从一组对象中提取对象共同的 特征,技能,构成一个类。类也是特征与技能的结合体,特征即数据并且是所有对象共享的数据,技能即函数属性并且是所有对象共享的函数属性。
①优点:解决了程序的扩展性,对某个对象进行修改,会立刻反映到整个体系中
②缺点:可控性差,无法预测最终的结果。
面向对象的程序设计并不是程序全部。对于软件质量来说,面向对象的程序设计只是用来解决扩展性的问题。
def 或是 class 都是在定义一个函数名。class 定义 类 camp 阵营 attack(self) 技能 nickname昵称 init 开始,初始
3)如何使用类:
一、实例化
类的实例化就会产生一个实例(对象)。 可以理解为类加()把虚拟的东西实例化,得到具体存在的值,叫做类的实例化。
class Garen: #定义一个类
camp = 'Demacia'
def attack(self):
print('attack')
g1 = Garen() #类的实例化,产生一个对象,可以调用类内包括的所有特征(共性)。
print(g1) #打印 #执行结果:
<__main__.Garen object at 0x00000000028C9CC0>
二、类通过.(点)的方式引用特征(类的变量)和技能(类的函数(类内部还是定义的函数,调用的话还是需要传入参数))
class Garen:
camp='Demacia'
def attack(self):
print('attack')
print(Garen.camp) #查看camp
print(Garen.attack) #打印数据类型
Garen.attack('nihao') #由于是调用有参函数,需要传值 #执行结果:
Demacia
<function Garen.attack at 0x000000000229C950>
attack
2、对象之间也有不同,及除了同性也有特性。例如昵称!
class Garen:
camp='Demacia' def __init__(self,nickname):
self.nick=nickname #给实例自己定义一个别名,由外部传入 #g1.nick = '草丛伦'
def attack(self,enemy):
# print('---------->',self.nick) #g1.nick
print('%s attack %s' %(self.nick,enemy)) g1=Garen('草丛伦') #类实例化,类Garen触发调用_init_ #Garen._init_(self,'NB')
g2=Garen('刘下')
print(g1.nick)
g1.attack('alex') #执行结果:
草丛伦
草丛伦 attack alex
self 指自己。
注意:类的实例化就会自动触发类内_init_函数的执行。
3、怎么调用类的特征与技能
注意:类与对象之间的绑定方法。调用绑定方法,python 会自动传值,会将调用者本身当作参数传给self,第一值。
print(gi.attack) #调用绑定方法,类绑定给g1
print(Garen.attack) #函数
class Garen:
camp='Demacia' def __init__(self,nickname):
self.nick=nickname #给实例自己定义一个别名,由外部传入 #g1.nick = '草丛伦'
def attack(self,enemy):
# print('---------->',self.nick) #g1.nick
print('%s attack %s' %(self.nick,enemy)) g1=Garen('草丛伦') #类实例化,类Garen触发调用_init_ #Garen._init_(self,'NB')
g2=Garen('刘下') print(g1.nick) #昵称
print(g1.camp) #阵营
print(g1.attack) #打印 查看绑定方法
print(Garen.attack) # 打印 函数 #执行结果:
草丛伦
Demacia
<bound method Garen.attack of <__main__.Garen object at 0x0000000002299D68>>
<function Garen.attack at 0x000000000229C9D8>
Garen.attack(参数)# 调用的是函数,需要传参
g1.attack('alex') #self = g1;enemy = 'alex'若是函数有多个值,就在赋值的时候,传入其他的参数。
print(g1.nick)
只要是对象触发的,调用的时候就会自动给调用的函数传值,将自身传到第一个参数self。若是函数有多个值,就在赋值的时候,对应的传入其他的参数。
class Garen:
camp='Demacia' def __init__(self,nickname):
self.nick=nickname #给实例自己定义一个别名,由外部传入 #g1.nick = '草丛伦'
def attack(self,enemy):
# print('---------->',self.nick) #g1.nick
print('%s attack %s' %(self.nick,enemy)) g1=Garen('草丛伦') #类实例化,类Garen触发调用_init_ #Garen._init_(self,'NB')
g2=Garen('刘下')
print(g2.nick)
print(g2.camp) #执行结果:
刘下
Demacia
三、总结:
1、类:一:实例化,二:引用名字(类名.变量名,类名.函数名) 得到一个内存地址,加()就能运行。
2、实例(对象):引用名字(实例名.类的变量,实例名.绑定方法,实例名.实例自己的变量名)
3、类:
优点:解决了程序的扩展性,对某个对象进行修改,会立刻反映到整个体系中
缺点:可控性差,无法预测最终的结果。
面向对象的程序设计并不是全部。对于软件质量来说,面向对象的程序设计只是用来解决扩展性的问题。
在python中,用变量表示特征,用函数表示方法,因而类是变量与函数的结合体,对象是变量与方法(指向类的函数)的结合体
4、类属性:特征(变量)和方法(函数)
5、类有两种方法:1.类的实例化;2.属性引用
1.实例化:
类名加括号就是实例化,会自动触发__init__函数的运行,可以用它来为每个实例定制自己的特征
2.属性引用:
类名.方法
6、对象也称为实例
对象的属性:对象本身就自有特征(变量)
对象的只有一种用法:属性引用
7、类的名称空间和对象的名称空间
创建一个类,就会创建一个类的名称空间,存放类中定义的属性:特征(数据)和方法(函数)
创建一个对象,及类的实例化,就会创建一个类的名称空间,存放对象的属性。
注意:对象就是类的实例化,类完成实例化的操作就已经将类的方法绑定到对象上,对象调用方法会现在自己的名称空间去找,找不到会去类的名称空间去找,再找不到会抛异常。它不会去找全局的定义。
查看类的名称空间 类名._dict_
查看对象的名称空间 对象名._dict_
绑定方法的核心在于‘绑定’,唯一绑定到一个确定的对象
可以调用:查
print(Garen.camp) #查
可以更改:改
Garen.camp='aaaaaa' #改
print(Garen.camp)
可以删除: 删
del Garen.camp #删除
print(Garen.camp)
可以添加: 增
Garen.x=1 #增加特征
print(Garen.x)
关于对象(实例)
可以调用: 查
g1=Garen('alex')
print(g1.nick) #查
可以更改: 改
g1.nick='asb' #改
print(g1.nick)
可以删除: 删
del g1.nick
print(g1.nick) #删
可以增加: 增
g1.sex='female'
print(g1.sex) #增加
四、面向对象的软件开发:
分为五部:
1、面向对象分析(object oriented analysis,OOA):
产品经理调研市场,考察,明确软件的用途和应用场景。
2、面向对象设计(object oriented design,OOD):
根据需求,对每一部分进行具体的设计,例如:类的设计
3、面向对象编程(object oriented programming,OOP):
将设计编程成代码
4、面向对象测试(object oriented test,OOT):
对写好的代码进行测试,发现错误并改正。面向对象的测试是用面向对象的方法进行测试,以类为测试的基本单元。
5、面向对象维护(object oriented soft maintenance,OOSM):
解决用户使用产品过程中出现的问题,或是增加新的功能。
面向对象编程思想:
1、设计的时候,一定要明确应用场景
2、由对象分析定义类的时候,找不到共同特征和技能不用强求
Py修行路 python基础 (十四)递归 及 面向对象初识及编程思想的更多相关文章
- Py修行路 python基础 (四)运算 copy
字符串的格式化 在字符串中插入 %s ,作为占位符,后边儿再定义插入变量. 算术运算 % 取模 判断奇偶数 / 除法 有小于号 // 取整除 返回整数部分 逻辑运算 and or not ' ...
- python递归 及 面向对象初识及编程思想
递归 及 面向对象初识及编程思想 一.递归 1.定义: 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. (1)递归就是在过程或函数里调用自身: (2)在使用递 ...
- Py修行路 python基础 (二十五)线程与进程
操作系统是用户和硬件沟通的桥梁 操作系统,位于底层硬件与应用软件之间的一层 工作方式:向下管理硬件,向上提供接口 操作系统进行切换操作: 把CPU的使用权切换给不同的进程. 1.出现IO操作 2.固定 ...
- Py修行路 python基础 (十二) 协程函数应用 列表生成式 生成器表达式
一.知识点整理: 1.可迭代的:对象下有_iter_方法的都是可迭代的对象 迭代器:对象._iter_()得到的结果就是迭代器 迭代器的特性: 迭代器._next_() 取下一个值 优点: 1.提供了 ...
- Py修行路 python基础 (二十四)socket编程
socket编程 一.客户端/服务端架构 客户端/服务端架构 即C/S架构,包括:1.硬件C/S架构,2.软件C/S架构. 互联网中处处都是C/S架构,学习socket 就是为了完成C/S架构的开发. ...
- Py修行路 python基础 (十八) 反射 内置attr 包装
一.isinstance 和 issubclass1.isinstance(obj,cls)检查是否obj是否是类 cls 的对象.2.issubclass(sub, super)检查sub类是否是 ...
- Py修行路 python基础 (二十)模块 time模块,random模块,hashlib模块,OS及sys模块
一.前提介绍: 可以开辟作用域的只有类,函数,和模块 for循环 if,else: 不能开辟自己的作用域 避免程序复用和重复调用,将这些写到一个.py文件中,做成一个模块,进行调 ...
- Py修行路 python基础 (十五)面向对象编程 继承 组合 接口和抽象类
一.前提回忆: 1.类是用来描述某一类的事物,类的对象就是这一类事物中的一个个体.是事物就要有属性,属性分为 1:数据属性:就是变量 2:函数属性:就是函数,在面向对象里通常称为方法 注意:类和对象均 ...
- Py修行路 python基础 (十九)面向对象进阶(下)
item系列 __slots__方法 __next__ 和 __iter__实现迭代器 析构函数 上下文管理协议 元类一.item系列 把对象操作属性模拟成字典的格式. 例如:对象名['key'] ...
随机推荐
- 在js中,ajax放在for中,ajax获取得到的变量有误
先看代码 for(var i=0;i<tds.length;i++){ mui.ajax(url+'api/client/gifts/isSigned', {data :{ sqId:" ...
- jquery attr与prop的区别与联系
最近开发中发现用attr无法设置checkbox的选中事件,在网上找了下说要用prop,所以总结下两者的区别. 1.操作的对象不同 attr:操作的是HTML文档节点属性 prop:操作的是js对象属 ...
- 连接mysql报错:error 2003 (hy000):can't connect to mysql server on 'localhost' (10061)
一.mysql 的bin目录下有个MySQLInstanceConfig.exe,运行就可以进行创建数据库实例,创建实例时也可以生成windows 服务,把服务设置成自动启动就可以了 二.安装在D盘的 ...
- python匿名函数 与 内置函数
一.匿名函数 1.定义: 匿名函数顾名思义就是指:是指一类无需定义标识符(函数名)的函数或子程序. 2.语法格式:lambda 参数:表达式 lambda语句中,开头先写关键字lambda,冒号 ...
- Puzzle Game HihoCoder - 1634
题目链接:https://cn.vjudge.net/problem/HihoCoder-1634 题目意思:可以让矩阵里的某一个数变成p,或者不修改.求最大子矩阵最小,输出最小值. 思路:请看下图 ...
- request对象和response对象,什么时候用,具体用哪一个,没有感觉
request对象和response对象,什么时候用,具体用哪一个,没有感觉
- PostgreSQL.conf文件配置详解[转]
一.连接配置与安全认证 1.连接Connection Settings listen_addresses (string) 这个参数只有在启动数据库时,才能被设置.它指定数据库用来监听客户端连接的 ...
- SVN 用户名切换
方法1:主要针对Window下安装了客户端设置 右键桌面-->settings-->Saved Data -->Authentication data -->clear 方法2 ...
- Bootstrap和IE何时能相亲相爱啊~
公司新项目,嘚瑟了一下,用了用Bootstrap... ... 发现了一个小坑(也许只是对我而言)... ... 使用了2.x的Jquery,在chrome等高版本浏览器一切顺利... ... 然,3 ...
- WPF XMAL获取元素的父元素,子元素
/// 获得指定元素的父元素 /// </summary> /// <typeparam name="T">指定页面元素</typeparam> ...