首页 > 代码库 > python基础----递归函数、认识类和对象
python基础----递归函数、认识类和对象
一、递归函数
定义:在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
1 #例子1 2 # age(5)=age(4)+2 n=5 age(n)=age(n-1)+2 3 # age(4)=age(3)+2 n=4 age(n)=age(n-1)+2 4 # age(3)=age(2)+2 n=3 age(n)=age(n-1)+2 5 # age(2)=age(1)+2 n=2 age(n)=age(n-1)+2 6 # age(1)=10 n=1 age(n)=10 7 8 # n=1 res=10 9 # n>1 res=age(n-1)+210 11 #递归------------代码实现12 def age(n):13 if n == 1:14 return 1015 else:16 return age(n-1)+2 #age(4)+217 print(age(5))
递归特性:
1. 必须有一个明确的结束条件
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
1 data = http://www.mamicode.com/[1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35] 2 # num=19 3 # i=0 4 # while True: 5 # if num == data[i]: 6 # print(‘find it‘) 7 # break 8 # i+=1 9 10 def search(num,data):11 print(data)12 if len(data) > 1:13 #二分14 mid_index=int(len(data)/2)15 mid_value=http://www.mamicode.com/data[mid_index]16 if num > mid_value: #19>1817 #num在列表的右边18 data=http://www.mamicode.com/data[mid_index:] #data[0:]-->[18]19 search(num,data)20 elif num < mid_value:21 #num在列表的左边22 data=http://www.mamicode.com/data[:mid_index]23 search(num,data)24 else:25 print(‘find it‘)26 return27 else:28 if data[0] == num:29 print(‘find it‘)30 else:31 print(‘not exists‘)32 33 # search(9527,data)34 search(15,data)35 # search(1,data)
1 import sys 2 sys.setrecursionlimit(10000) #setrecursionlimit 最大递归深度 3 4 def func(n): 5 if n == 10: 6 return 7 print(‘from func‘) 8 func(n-1) 9 10 func(10)
二、认识类
类有两种作用:属性引用和实例化
属性引用(类名.属性)
1 class Garen:2 camp=‘Demacia‘3 def attack(self):4 print(‘attack‘)
1 #引用类的特征(类的变量)和技能(类的函数)2 print(Garen.camp)3 print(Garen.attack)4 Garen.attack(1231231)
实例化(__init__与self)
1 x=int(10)2 print(x)3 4 obj=Garen() #实例化5 print(obj)
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 11 g1=Garen(‘草丛伦‘) #Garen.__init___(g1,‘草丛伦‘)12 g2=Garen(‘猥琐轮‘)13 print(g1.nick)14 g1.attack(‘alex‘)15 16 print(g1.nick)17 print(g1.camp)18 print(g1.attack)19 print(Garen.attack)20 21 Garen.attack() #调用的是函数22 g1.attack() #self=g123 Garen.attack(g1)24 25 print(g2.nick)26 print(g2.camp)
1 #总结: 2 #类:一:实例化,二:引用名字(类名.变量名,类名.函数名) 3 #实例:引用名字(实例名.类的变量,实例名.绑定方法,实例名.实例自己的变量名) 4 5 class Garen: 6 camp=‘Demacia‘ 7 8 def __init__(self,nickname): 9 self.nick=nickname #g1.nick=‘草丛伦‘10 def attack(self,enemy):11 # print(‘---------->‘,self.nick) #g1.nick12 print(‘%s attack %s‘ %(self.nick,enemy))13 14 # print(Garen.camp) #查15 # Garen.camp=‘aaaaaa‘ #改16 # print(Garen.camp)17 #18 # # del Garen.camp #删除19 # # print(Garen.camp)20 #21 # Garen.x=122 # print(Garen.x)23 24 25 g1=Garen(‘alex‘)26 # print(g1.nick)27 # g1.nick=‘asb‘28 # print(g1.nick)29 # del g1.nick30 # print(g1.nick)31 32 # g1.sex=‘female‘33 # print(g1.sex)
三、认识对象
面向过程的程序设计的核心是过程,过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西。
优点是:极大的降低了程序的复杂度
缺点是:一套流水线或者流程就是用来解决一个问题,生产汽水的流水线无法生产汽车,即便是能,也得是大改,改一个组件,牵一发而动全身。
应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。
面向对象的程序设计的核心是对象,要理解对象为何物,必须把自己当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也可以创造出来。面向对象的程序设计好比如来设计西游记,如来要解决的问题是把经书传给东土大唐,如来想了想解决这个问题需要四个人:唐僧,沙和尚,猪八戒,孙悟空,每个人都有各自的特征和技能(这就是对象的概念,特征和技能分别对应对象的数据属性和方法属性),然而这并不好玩,于是如来又安排了一群妖魔鬼怪,为了防止师徒四人在取经路上被搞死,又安排了一群神仙保驾护航,这些都是对象。然后取经开始,师徒四人与妖魔鬼怪神仙交互着直到最后取得真经。如来根本不会管师徒四人按照什么流程去取。 ♥♥♥♥♥?????♥♥♥♥♥ (举例很形象,看懂你就明白了)
面向对象的程序设计的
优点是:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。
缺点:可控性差,无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即便是上帝也无法预测最终结果。于是我们经常看到一个游戏人某一参数的修改极有可能导致阴霸的技能出现,一刀砍死3个人,这个游戏就失去平衡。
应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方
面向对象的程序设计并不是全部。对于一个软件质量来说,面向对象的程序设计只是用来解决扩展性。
对象/实例只有一种作用:属性引用
1 #对象/实例本身其实只有数据属性 2 >>> g1.nickname 3 ‘草丛伦‘ 4 >>> g1.aggressivity 5 >>> g1.life_value 6 ‘‘‘ 7 查看实例属性 8 同样是dir和内置__dict__两种方式 9 特殊实例属性10 __class__11 __dict__12 ....13 ‘‘‘
对象/实例本身只有数据属性,但是python的class机制会将类的函数绑定到对象上,称为对象的方法,或者叫绑定方法
1 >>> g1.attack #对象的绑定方法2 <bound method Garen.attack of <__main__.Garen object at 0x101348dd8>>3 4 >>> Garen.attack #对象的绑定方法attack本质就是调用类的函数attack的功能,二者是一种绑定关系5 <function Garen.attack at 0x101356620>
对象的绑定方法的特别之处在于:obj.func()会把obj传给func的第一个参数。
python基础----递归函数、认识类和对象