一、递归
如果一个函数在内部不调用其它函数,而是自己,这个函数就是递归函数;
优点:定义简单,逻辑清晰
特性:
1)必须有一个明确的结束条件;
2)超出一定调用次数,会导致栈溢出;
递推
回溯
1、累计求和
def funa(n):
sum1 = 0
for i in range(1, n + 1):
sum1 += i # sum1 = sum1 + i
print(sum1)
funa(3)
输出:6
2、递归函数
lan_zi(第二天) = lan_zi(第一天) + dan(2)个
lan_zi(第三天) = lan_zi(第二天) + dan(3)个
funb(n) = funb(n-1) + n
def f(n):
if n > 0:
return n + f(n-1)
else: # n <= 0
return 0
print(f(3))
输出:6
解析:
f(3)
= f(2) + 3
= f(1) + 2 + 3
= f(0) + 1 + 2 + 3
= 0 + 1 + 2 +3
|
3、斐波那契函数: 1,1,2,3,5,8... 项
假设我定义这个序列的第n项为函数f(n)
f(n) = f(n-1) + f(n-2)
def f(n):
if n <= 1:
return n
else:
return f(n-1) + f(n-2)
print(f(3))
输出:2
解析:
f(3)
= f(1) + f(2)
= 1 + f(0)+f(1)
= 1+ 1 +1
= 3
---- f(0) 必须是0 f(1) 必须是1
|
4、斐波那契序列 写出前面10项的序列
def f(n):
if n <= 1:
return n
else:
return f(n-1) + f(n-2)
lst = []
for i in range(1,11):
lst.append(f(i))
print(lst)
输出:[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
二、类和对象
1、为啥要使用类和对象?
- 1)方便复用;
- 2) 方便扩展;
- 3) 方便维护;
def make_yazui():
print('鸭嘴制作完成')
def make_erduo():
print('鸭耳制作完成')
make_yazui()
make_erduo()
输出:鸭嘴制作完成
鸭耳制作完成
def make_zhuzui():
print('猪嘴制作完成')
def make_zhuer():
print('猪耳朵制作完成')
make_zhuzui()
make_zhuer()
输出:猪嘴制作完成
猪耳朵制作完成
面向过程 ---- 过程
面向对象 ---- 对象 谁来帮我完成这件事
面向对象的三大特征:封装 继承 多态
类:总称 ---抽象的概念
对象:实实在在具体的
举例:
水果---- 类
车厘子 橘子 苹果 草莓 香蕉---对象
|
object是python里所有类的最*的父类
类名习惯上首字母大写
类的定义:
class 类名(): # 类名 或 类名(object)
pass
例:
class Hero(): # 还可以写成Hero或Hero(object)
pass
|
创建对象: 类名()
创建对象/实例化对象 --- 一个类可以创建很多个对象
class Hero():
pass
hero1 = Hero()
hero2 = Hero()
hero3 = Hero()
print(id(hero1))
print(id(hero2))
print(id(hero3))
class Hero():
pass
hero = Hero()
hero.name = 'wang' # 对象名.属性 = 值
hero.age = 30
# # 获取属性
print(f'名字是{hero.name},年龄是{hero.age}岁')
输出:名字是wang,年龄是30岁
2、方法
class Hero(object):
def move(self): # 方法
print('正在前往事发地点……')
hero1 = Hero()
# 获取方法 对象名.方法名()
hero1.move()
hero2 = Hero()
hero2.move()
输出:正在前往事发地点……
正在前往事发地点……
三、构造方法
__init__():初始化 系统自带的--手机一开机我就有的功能
在创建对象(实例化对象)会自动调用该方法----即拥有这个方法的所有东西
类属性:在类的内部,在方法之外
实例属性:在方法内部 "self.变量名= 值",实例属性一般在__init__()
方法里self参数一定是第一个参数,对象自动传参给self
class A:
def __init__(self):
print('哈哈')
a = A()
输出:哈哈
class Hero():
# money = 10000 # 类属性
def __init__(self):
self.name = '奥特曼' # 实例属性
self.hp = 200 # 生命值
self.at = 450 # 战斗力
def move(self):
print(f'{self.name}正在移动中...')
def attack(self):
print(f'{self.name}的生命值是{self.hp},发出了一招战斗,战斗力为{self.at}')
hero1 = Hero()
hero1.move()
hero1.attack() # 对象可以访问实例属性
输出:奥特曼正在移动中...
奥特曼的生命值是200,发出了一招战斗,战斗力为450
hero2 = Hero()
hero2.move()
hero2.attack()
输出:奥特曼正在移动中...
奥特曼的生命值是200,发出了一招战斗,战斗力为450
类的封装 ---- 用统一模板,实现千人千面 -----框架一样,数值(血肉)不一样
class Hero():
def __init__(self, name, hp, at):
self.name = name # 实例属性
self.hp = hp # 生命值
self.at = at # 战斗力
def move(self):
print(f'{self.name}正在移动中...')
def attack(self):
print(f'{self.name}的生命值是{self.hp},发出了一招战斗,战斗力为{self.at}')
hero1 = Hero('1号',800,300)
hero1.move()
hero1.attack() # 对象可以访问实例属性
输出:1号正在移动中...
1号的生命值是800,发出了一招战斗,战斗力为300
hero2 = Hero('2号',500,200)
hero2.move()
hero2.attack()
输出:2号正在移动中...
2号的生命值是500,发出了一招战斗,战斗力为200
三、析构方法
__del__()
作用:主要是销毁/删除临时的变量
class Person:
def __init__(self):
print('这是构造方法')
def __del__(self):
print('被销毁了') # 析构方法
p = Person()
print('哈哈')
print('哈哈')
print('哈哈')
输出:这是构造方法
哈哈
哈哈
哈哈
被销毁了
class Person:
def __init__(self):
print('这是构造方法')
def __del__(self):
print('被销毁了') # 析构方法
p = Person()
del p # 删除对象时,触发__del__()调用
print('哈哈')
print('哈哈')
print('哈哈')
输出:这是构造方法
被销毁了
哈哈
哈哈
哈哈
str(): 把其它类型转换为字符串类型
__str__() 打印对象时,设置输出该方法的返回值
class A:
def __str__(self):
return '哈哈'
a = A()
print(a)
输出:哈哈