递归函数 recursion function
什么是递归函数:
函数直接或间接的调用自身
示例:
def f():
print("f()被调用")
f() # 执行函数自身
print("f()调用结束")
f()
print("程序结束") # 此语句永远不会被打印
递归说明:
递归一定要控制递归的层数,当符合某一个条件时要终止递归
几乎所有的递归都能用while循环来代替.
示例:
# 打印1-100之间的数
# 循环实现
def number(begin, end):
for x in range(begin, end + 1):
print(x, end=' ')
number(1, 100)
# 递归实现
def number(begin, end):
print(begin, end=' ')
number(begin + 1, end)
number(1, 100)
案例:
# 用递归实现打印100-1
def number(stop):
if stop < 1:
return
print(stop, end=' ')
number(stop - 1)
number(100)
思考:
计算1+2+3+4+....+ n 的和
能否用递归实现?????
假设n为100
1 + 2 + 3 + 4 + ..... + 98 + 99 + 100
(1 + 2 + 3 + 4 + ..... + 98 + 99) + 100
((1 + 2 + 3 + 4) + ..... + 98 + 99) + 100
(((1 + 2 + 3) + 4) + ..... + 98 + 99) + 100
((((1 + 2) + 3) + 4) + ..... + 98 + 99) + 100
(((((1) + 2) + 3) + 4) + ..... + 98 + 99) + 100
((((1 + 2) + 3) + 4) + ..... + 98 + 99) + 100
(((3 + 3) + 4) + ..... + 98 + 99) + 100
(((6 + 4) + ..... + 98 + 99) + 100
((10 + ..... + 98 + 99) + 100
5050
def mysum(n):
if n == 1:
return 1
return n + mysum(n-1)
print(mysum(100))
练习:
用递归的方法求阶乘
1 * 2 * 3
def myfac(n):
....
print(myfac(3)) # 6
print(myfac(5)) # 120
print(myfac(100)) # ?????
递归的实现方法:
先假设函数已经实现
n! = n*(n-1)!
递归的优缺点:
优点:
递归可以把问题简单化,让思路更为清晰,代码更简洁
缺点:
递归因系统环境影响大,当递归深度太大时,可能会得到不可预知的结果
应用案例:
搜索文件等
装饰器 decorators(专业提高篇)
什么是装饰器:
装饰器是一个函数,主要作用是用来包装另一个函数或者类
包装的目的是在不改变原函数名(或类名)的情况下,改变被包装对象的行为
函数装饰器:
指一个装饰器函数传入一个函数,返回的也是一个函数
语法:
def 装饰器函数名(参数):
语句块
return 函数对象
# 装饰另一个函数的语法:
@装饰器函数名<换行>
def 函数名(参数列表):
语句块
示例:
def f1():
print("f1()函数被调用")
f1()
# f1将被调用
# f1()函数被调用
# f1被调用之后
# 想把f1的功能改为:
def f1():
print("f1将被调用")
print("f1()函数被调用")
print("f1被调用之后")
带有参数的装饰器函数示例
示例:
模拟银行存取钱业务:
def savemoney(name, x):
print(name, "存钱", x, "元")
def withdraw(name, x):
print(name, "取钱", x, "元")
见deco4.py
函数的文档字符串:
语法:
def 函数名(参数列表):
"函数文档字符串"
语句块
说明:
函数文档字符串通常用来说明本函数的功能和用法
在交互模式下,可以键入:help(函数名) 查看文档字符串
def mysum(n):
"""mysum(整数)
返回1 + 2 + 3 + .... + n 的和
我是文档字符串
"""
print("hello")
'''
我是第二个文档字符串,别人看不到我...
'''
函数属性:
__name__属性
用来记录函数名
说明:
以双下划线开头,以双下划线结尾的标识符通常代表python的特殊属性
示例:
def abcd():
pass
a = abcd
print("a绑定的函数名是:", a.__name__)
print("abcd绑定的函数名是:", abcd.__name_
语法:
对象.属性
函数的__doc__ 属性:
用于记录文档字符串
示例:
def cba():
"你好,我是文档字符串..."
pass
模块 Module
什么是模块:
模块是一个包含有一系列变量,函数,类等组成的程序组
模块是一个文件,模块文件名通常以 .py 结尾
作用:
1. 让一些相关的变量,函数,类有逻辑的组织在一起,使逻辑结构更加清晰
2. 模块中的变量,函数和类可提供给其它模块或程序使用
模块的分类:
1. 内置模块(builtins),在解析器的内部可以直接使用
2. 安装的标准库,安装Python时已安装且可直接使用
3. 第三方模块(通常为开源), 需要自己安装
4. 用户自己编写的模块(可以作为其他人的第三方模块)
模块的导入 import:
import 语句:
语法:
import 模块名1 [as 模块新名1] [, 模块名2[as 模块新名2]] ...
例如:
import math
import sys, os
import math as m
作用:
将某模块的整体导入到当前模块中
用法:
模块名.变量名 # 也叫模块的属性
模块名.函数名(调用实参)
查看模块内有哪儿些函数或变量的方法:
dir(obj) 返回所有属性的字符串的列表
help(obj) 查看模块的文档字符串
练习:
写一个程序,输入圆的半径,打印出圆的周长和面积
要求用math模块中的数据
from import 语句
语法:
from 模块名1 import 模块属性名1 [as 属性名新名1] [, 模块属性名2 [as 属性新名2]
作用:
将模块内的一个或多个属性导入到当前模块
示例:
from math import pi
print(pi * 10 ** 2)
from math import factorial as fac
print(fac(5)) # 120
from import * 语句
语法:
from 模块名 import *
作用:
将某模块的所有属性导入到当前模块
示例:
from math import *
print(pi * 10 ** 2)
print(factorial(5))
dir函数
dir([对象]) 返回一个字符串列表
作用:
如果没有参数调用,则返回当前作用域内的所有变量的列表
如果给定一个对象作为参数,则返回这个对象所有变量的列表
对于模块,返回这个模块的全部变量
对于一个类对象,返回类对象的所有变量
内置模块
sys, time, math
标准库模块
random, os, re ....
数学模块
模块名: math
注:
linux 下为内建模块
Mac OS X 下为标准库模块
变量:
math.e 自然对数e
math.pi 圆周率pi
函数:
math.ceil(x) 对x向上取整,如x = 1.2 返回2
math.floor(x) 对x向下取整, 如x = 1.2 返回1
math.sqrt(x) 返回x的平方根
math.factorial(x) 求x的阶乘
math.log(x[, base]) 返回以base为底x的对数,如果不给出base,则以自然对数e为底
math.log10(x) 求以10为底x的对数
math.pow(x, y) 返回x**y
math.fabs(x) 返回浮点数x的绝对值
角度/弧度转换
math.degrees(x) 弧度转角度
math.radians(x) 角度转弧度
三角函数:
math.sin(x) 正弦(x为弧度)
math.asin(x) 反正弦
...