递归函数
- 函数间接或直接调用自己
- 递归必须要求有递归出口
# 阶乘
def func_jc(n):
if n >= 1:
return n * func_jc(n-1)
return 1
print(func_jc(10))
3628800
# 斐波那契数列
def func_fbnq(n):
if n == 1 or n == 2:
return 1
return func_fbnq(n-1) + func_fbnq(n-2)
print(func_fbnq(10))
55
# 汉诺塔
a = "A"
b = "B"
c = "C"
def hnt(a,b,c,n):
if n == 1:
print("{}=>{}".format(a,c))
return None
if n == 2:
print("{}=>{}".format(a,c))
print("{}=>{}".format(a,b))
print("{}=>{}".format(b,c))
return None
hnt(a,c,b,n-1)
print("{}=>{}".format(a,c))
hnt(b,a,c,n-1)
# 一个盘子
hnt(a,b,c,1)
A=>C
# 两个盘子
hnt(a,b,c,2)
A=>C
A=>B
B=>C
面向对象
-
常用名词
- oo:面向对象
- ooa:分析
- ood:设计
- oop:编程
- ooi:实现
- ooa -> ood -> oop
-
类 vs 对象
- 类:抽象,共性
- 对象:具体,个性
-
类的内容
- 动作,函数
- 属性,变量
-
定义类:class关键字
-
类命名:
- 大驼峰:首字母大写
## 定义学生类
class Student():
'''
此处定义一个空类
pass是关键字,表示占位,wu无意义
'''
pass
# 定义一个对象,python不用new关键字
# 实例化
xiaobai = Student()
class PyStudent():
name = "小白"
age = 18
'''
this指的是当前类的实例,作为方法的第一个形参
'''
def getName(this,n,a):
this.name = n
this.age = a
print("姓名:"+this.name + "\t年龄:"+str(this.age))
this.work = "程序员"
print(this.name +"的工作:"+this.work)
return None
xiaobai = PyStudent()
print(xiaobai.name)
print(xiaobai.age)
# xiaobai.getName()
# print(xiaobai.work)
# 实例调用类的方法,默认把自己作为第一个参数传进去
xiaobai.getName("dabai",12)
print("姓名:"+PyStudent.name + "\t年龄:"+str(PyStudent.age))
小白
18
姓名:dabai 年龄:12
dabai的工作:程序员
姓名:小白 年龄:18
类的变量作用域的问题
- 类变量:属于类的变量
- 实例变量:属于实例的变量
- 访问实例的属性,如果实例没有定义该属性,则默认去访问类的该属性,没有就报错
访问类的属性
- 在类里面强制访问类的属性,则需要使用 class ,前后有两个下划线
- 类方法:不传实例this,类方法中不允许访问实例的任何属性,只允许访问类的属性,用类名或者 class
class PyStudent():
name = "小白"
age = 18
'''
this指的是当前类的实例,作为方法的第一个形参
'''
def getName(this,n,a):
this.name = n
this.age = a
print("姓名:"+this.name + "\t年龄:"+str(this.age))
this.work = "程序员"
print(this.name +"的工作:"+this.work)
return None
def sos():
print("sos")
print("姓名:"+PyStudent.name + "\t年龄:"+str(PyStudent.age))
print("姓名:"+__class__.name + "\t年龄:"+str(__class__.age))
PyStudent.sos()
sos
姓名:小白 年龄:18
姓名:小白 年龄:18
构造函数
- 类实例化的时候,执行的一些基础性的操作的方法
- 实例化的时候自动执行
- 第一个参数this必须有
class Student():
def __init__(this,height,weight):
this.height = height
this.weight = weight
xiaoming = Student(180,50)
print(xiaoming.height)
print(xiaoming.weight)
180
50
面向对象的三大特征
- 继承
- 封装
- 多态
继承
- 子类可以使用父类定义的属性和行为等
- 继承实现
- 父类,基类,超累
- 所有类都必须有一个父类,如果没有,则默认为是object的子类
- python子类可以继承多个父类
class Person():
pass
# Teacher是Person的子类,父类写在括号中,可以有多个
class Teacher(Person):
pass
t = Teacher()
print(t)
<__main__.Teacher object at 0x0000024A4C038C88>
class Bird():
fly = "we can fly"
def flying(this):
print("飞呀飞呀")
class BirdMan(Person,Bird):
pass
bm = BirdMan()
bm.flying()
飞呀飞呀
issubclass检测是否是子类
- 可以用来检测两个类的父子关系
print(issubclass(BirdMan,Bird))
print(issubclass(BirdMan,Person))
print(issubclass(BirdMan,Teacher))
True
True
False
构造函数的继承
- 构造函数默认继承
- 一旦子类dingyie定义了构造函数,则不再自动调用父类构造函数,此时需要显示调用父类构造函数,即super.init()