一、递归

1、定义:

  在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

  (1)递归就是在过程或函数里调用自身;
  (2)在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。

  1. 1 def age(n):
  2. 2 if n ==1: #条件判定
  3. 3 return 10 #返回一个结果
  4. 4 else:
  5. 5 return age(n-1)+2 #重复调用函数本身,系统会将运算的结果存放到栈,然后再依次的进行取值调用。
  6. 6 print(age(5)) #打印结果

 执行结果:18

2、优缺点:  

  递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

  递归的缺点:递归算法解题的运行效率较低。在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。

  1. def func():
  2. print("*******")
  3. func()
  4. func()
  5.  
  6. #执行结果
  7. [Previous line repeated 993 more times]
  8. *******
  9. File "F:/py_fullstack_s4/day26/递归.py", line 8, in func
  10. *******
  11. print("*******")
  12. *******
  13. RecursionError: maximum recursion depth exceeded while calling a Python object

3、递归编程的注意点:

  1. 必须有一个明确的结束条件。

  2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少。

  3.递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)。

4、此处引出一个新的知识点:二分法

  二分法,是一种快速查找的方法,时间复杂度低,逻辑简单易懂,总的来说就是不断的除以2除以2...

  他主要应用于有序序列中,原理是每次查找都将原序列折半,逐渐缩小查找范围的一种算法。应用于递归,循环之中,直到找到结果。

  1. #运用 递归 和 二分法 的运算方式,查找列表中的某个值
  2. data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]
  3. num = int(input("please input your want to find number:"))
  4. def search(num,data):
  5. if len(data) > 1: #排除列表分割,仅剩一个元素的情况
  6. #二分法#
  7. a = int(len(data)//2) #将计算列表的长度,除以2 取整数
  8. mid_value = data[a] #取当前中间的值
  9. if num > mid_value: #要找的值 大于 中间的值
  10. data = data[a:] #将原列表从中间值往后,取出来,构建一个新列表
  11. search(num,data) #递归判断
  12. elif num < mid_value: #要找的值 小于 中间的值
  13. data = data[:a] #将原列表开始到中间值,取出来,构建一个新列表
  14. search(num,data) #递归判断
  15. else: #正好是这个值
  16. print("find it!!",num)
  17. return #打印
  18. else: #判断列表分割,仅剩一个元素的情况
  19. if data[0] == num:
  20. print('find it!! %s'%data[0])
  21. else: #列表中没有这个值
  22. print('not this num %s'%num)
  23.  
  24. search(num,data)
  25.  
  26. #执行结果:
  27. please input your want to find number:18
  28. find it!! 18

二、函数式编程介绍

1、用def模仿数学中函数的方式,传一个值,就得一个结果。不会修改外部的状态。
2、代码非常的精简,直接导致可读性非常差。

三、面向对象的程序设计

1、前提铺垫:

  python中一切皆为对象,python 3统一了类与类型的概念,类型即是类。例如:int,str,list,等等……

  编程语言中,是先有了类,然后再产生一个个对象。而现实生活中正好相反。

  明确一点:面向对象编程是一种编程方式,此编程方式的功能需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用

  类就是一个模板,模板里可以包含创建多个函数,函数里实现自定义的功能

  对象则是根据模板创建的实例,通过实例(对象)可以执行类中定义的函数

2、语法:

  1)创建类:class是关键字,表示类 class *** #创建类
  2)创建对象:类名称后加括号 将结果赋给一个变量 即可 x = ***() #创建对象

  1. 1 class hello: #任意定义一个类
  2. 2 camp = 'hello world'
  3. 3 def f(self):
  4. 4 print("f")
  5. 5 h = hello() # 类实例化
  6. 6 print(h) #打印
  7. 7
  8. 8 #执行结果:
  9. 9
  10. 10 <__main__.hello object at 0x00000000026C9630>

3、类与对象

1)什么是对象:
  以游戏举例:英雄联盟,每个玩家选一个英雄,每个英雄都有自己的特征和和技能,特征即数据属性,技能即方法属性,特征与技能的结合体就一个对象。

2)什么是类:
  从一组对象中提取对象共同的 特征,技能,构成一个类。类也是特征与技能的结合体,特征即数据并且是所有对象共享的数据,技能即函数属性并且是所有对象共享的函数属性。 

  ①优点:解决了程序的扩展性,对某个对象进行修改,会立刻反映到整个体系中
  ②缺点:可控性差,无法预测最终的结果。
  面向对象的程序设计并不是程序全部。对于软件质量来说,面向对象的程序设计只是用来解决扩展性的问题。

def 或是 class 都是在定义一个函数名。class 定义 类    camp 阵营    attack(self) 技能    nickname昵称    init 开始,初始

3)如何使用类:
 一、实例化

  类的实例化就会产生一个实例(对象)。 可以理解为类加()把虚拟的东西实例化,得到具体存在的值,叫做类的实例化。

  1. class Garen: #定义一个类
  2. camp = 'Demacia'
  3. def attack(self):
  4. print('attack')
  5. g1 = Garen() #类的实例化,产生一个对象,可以调用类内包括的所有特征(共性)。
  6. print(g1) #打印
  7.  
  8. #执行结果:
  9. <__main__.Garen object at 0x00000000028C9CC0>

 二、类通过.(点)的方式引用特征(类的变量)和技能(类的函数(类内部还是定义的函数,调用的话还是需要传入参数))

  1. class Garen:
  2. camp='Demacia'
  3. def attack(self):
  4. print('attack')
  5. print(Garen.camp) #查看camp
  6. print(Garen.attack) #打印数据类型
  7. Garen.attack('nihao') #由于是调用有参函数,需要传值
  8.  
  9. #执行结果:
  10. Demacia
  11. <function Garen.attack at 0x000000000229C950>
  12. attack

2、对象之间也有不同,及除了同性也有特性。例如昵称!

  1. class Garen:
  2. camp='Demacia'
  3.  
  4. def __init__(self,nickname):
  5. self.nick=nickname #给实例自己定义一个别名,由外部传入 #g1.nick = '草丛伦'
  6. def attack(self,enemy):
  7. # print('---------->',self.nick) #g1.nick
  8. print('%s attack %s' %(self.nick,enemy))
  9.  
  10. g1=Garen('草丛伦') #类实例化,类Garen触发调用_init_ #Garen._init_(self,'NB')
  11. g2=Garen('刘下')
  12. print(g1.nick)
  13. g1.attack('alex')
  14.  
  15. #执行结果:
  16. 草丛伦
  17. 草丛伦 attack alex

self 指自己。

注意:类的实例化就会自动触发类内_init_函数的执行。

3、怎么调用类的特征与技能

注意:类与对象之间的绑定方法。调用绑定方法,python 会自动传值,会将调用者本身当作参数传给self,第一值。
print(gi.attack) #调用绑定方法,类绑定给g1
print(Garen.attack) #函数

  1. class Garen:
  2. camp='Demacia'
  3.  
  4. def __init__(self,nickname):
  5. self.nick=nickname #给实例自己定义一个别名,由外部传入 #g1.nick = '草丛伦'
  6. def attack(self,enemy):
  7. # print('---------->',self.nick) #g1.nick
  8. print('%s attack %s' %(self.nick,enemy))
  9.  
  10. g1=Garen('草丛伦') #类实例化,类Garen触发调用_init_ #Garen._init_(self,'NB')
  11. g2=Garen('刘下')
  12.  
  13. print(g1.nick) #昵称
  14. print(g1.camp) #阵营
  15. print(g1.attack) #打印 查看绑定方法
  16. print(Garen.attack) # 打印 函数
  17.  
  18. #执行结果:
  19. 草丛伦
  20. Demacia
  21. <bound method Garen.attack of <__main__.Garen object at 0x0000000002299D68>>
  22. <function Garen.attack at 0x000000000229C9D8>

Garen.attack(参数)# 调用的是函数,需要传参
g1.attack('alex') #self = g1;enemy = 'alex'若是函数有多个值,就在赋值的时候,传入其他的参数。

print(g1.nick)

只要是对象触发的,调用的时候就会自动给调用的函数传值,将自身传到第一个参数self。若是函数有多个值,就在赋值的时候,对应的传入其他的参数。

  1. class Garen:
  2. camp='Demacia'
  3.  
  4. def __init__(self,nickname):
  5. self.nick=nickname #给实例自己定义一个别名,由外部传入 #g1.nick = '草丛伦'
  6. def attack(self,enemy):
  7. # print('---------->',self.nick) #g1.nick
  8. print('%s attack %s' %(self.nick,enemy))
  9.  
  10. g1=Garen('草丛伦') #类实例化,类Garen触发调用_init_ #Garen._init_(self,'NB')
  11. g2=Garen('刘下')
  12. print(g2.nick)
  13. print(g2.camp)
  14.  
  15. #执行结果:
  16. 刘下
  17. 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、由对象分析定义类的时候,找不到共同特征和技能不用强求

 

python递归 及 面向对象初识及编程思想的更多相关文章

  1. Py修行路 python基础 (十四)递归 及 面向对象初识及编程思想

    一.递归 1.定义: 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. (1)递归就是在过程或函数里调用自身: (2)在使用递归策略时,必须有一个明确的递归结束条件 ...

  2. python进阶之面向对象初识

    面向对象 不同于面向过程的编程思想,面向对象是一种将程序抽象为一个个对象的编程思想,能更好的处理现实世界到的一些复杂问题. 通过下面的例子来初步了解面向对象的编程方式. class Person: # ...

  3. Python学习一(面向对象和函数式编程)

    学习了一周的Python,虽然一本书还没看完但是也收获颇多,作为一个老码农竟然想起了曾经荒废好久的园子,写点东西当做是学习笔记吧 对Python的语法看的七七八八了,比较让我关注的还是他编程的思想,那 ...

  4. python记录_day15 面向对象初识

    一.面向过程和面向对象 1.面向过程 以我为中心,做一件事先干什么,在干什么,后干什么,有一套清楚完整的流程.核心是“过程”. 优点:将要解决的问题流程化, 编写相对简单 缺点:可扩展性差 2.面向对 ...

  5. 第八篇:python基础_8 面向对象与网络编程

    本篇内容 接口与归一化设计 多态与多态性 封装 面向对象高级 异常处理 网络编程 一. 接口与归一化设计 1.定义 (1)归一化让使用者无需关心对象的类是什么,只需要知道这些对象都具备某些功能就可以了 ...

  6. Python 基础之面向对象初识与类的封装

    一.面向对象类的初识 1.类的定义 #三种方式:#1.class MyClass:    pass #2.推荐class MyClass():    pass #3.class MyClass(obj ...

  7. Python基础之面向对象:1、面向对象及编程思想

    一.人狗大战 1.需求 用代码模拟人.狗打架的小游戏 人和狗种类不同,因此双方的属性各不相同 推导一: 人和狗各有不同属性 使用字典方式储存属性较为方便,并可储存多种属性 # 1.在字典内储存'人'属 ...

  8. python基础语法9 生成器,面向对象编程思想,三元表达式,列表生成式,生成器表达式(生成式),匿名函数,内置函数

    生成器 1.什么是生成器? 生成的工具. 生成器是一个 "自定义" 的迭代器, 本质上是一个迭代器. 2.如何实现生成器 但凡在函数内部定义了的yield, 调用函数时,函数体代码 ...

  9. Python面向对象01 /面向对象初识、面向对象结构、类、self、实例化对象

    Python面向对象01 /面向对象初识.面向对象结构.类.self.实例化对象 目录 Python面向对象01 /面向对象初识.面向对象结构.类.self.实例化对象 1. 面向对象初识 2. 面向 ...

随机推荐

  1. 【vim使用】

    nano,与vim相似的一个文本编辑工具,在git merge时默认使用 https://www.vpser.net/manage/nano.html 这里介绍一下如何退出nano 按Ctrl+X 如 ...

  2. tornado web应用程序结构

    tornado web 应用程序通常包含一个或者多个RequestHandler 子类,一个Application 对象来为每个控制器路由到达的请求和一个mian()函数 import tornado ...

  3. Linux(6)- redis发布订阅/持久化/主从复制/redis-sentinel/redis-cluster、nginx入门

    一.redis发布订阅 Redis 通过 PUBLISH .SUBSCRIBE 等命令实现了订阅与发布模式. 其实从Pub/Sub的机制来看,它更像是一个广播系统,多个Subscriber可以订阅多个 ...

  4. Java String.split() 使用注意

    java的split()方法用于字符串中根据指定的字符进行分割,得到的是一个字符串数组 public String[] split(String regex) Splits this string a ...

  5. phpexcel导出带生成图片完美案例

    // 导出exl public function look_down(){ $id = I('get.id'); $m = M ('offer_goods'); $where['offer_id'] ...

  6. linux命令(6/11)--修改文件的用户组chgrp和文件所有者chown

    在lunix系统里,文件或目录的权限的掌控以拥有者及所诉群组来管理.可以使用chgrp指令取变更文件与目录所属群组,这种方式采用群组名称或群组识别码都可以.Chgrp命令就是change group的 ...

  7. HDU4627

    /*找规律,n是奇数那么就是n/2和n/2+1 如果n是偶数,那就是两种情况n/2-1,和n/2-2两种,比较一下大小就可以 思路来自:http://www.cnblogs.com/freezhan/ ...

  8. js算法-快速排序(Quicksort)

    快速排序(英语:Quicksort),又称划分交换排序(partition-exchange sort),简称快排,一种排序算法,最早由东尼·霍尔提出.在平均状况下,排序n个项目要O(nLogn)次比 ...

  9. 总结一下TODO的用法

      1.设置任务的标签 WINDOW->preference->java->complier->task tags加一个 DONE:NORMAL表示已经完成的任务2. java ...

  10. COS-5资源分配与调度

    操作系统是用户和计算机的接口,同时也是计算机硬件和其他软件的接口.操作系统的功能包括管理计算机系统的硬件.软件及数据资源,控制程序运行,改善人机界面,为其它应用软件提供支持,让计算机系统所有资源最大限 ...