一、函数
1. 使用函数的好处
减少重复代码(代码重用);
保持代码一致性,易维护;
方便修改,易扩展;
2. 定义函数
def func(x): # def 关键字,func 函数名,x 形参(也可以不传入参数)
""" This function document""" # 函数说明 y = x+1 # 函数体 return y # 返回值 print(func(4))
3. 函数参数
位置参数、默认参数、可变参数、关键字参数
# 位置参数:形参与实参一一对应
def func(x, y, z=7):
return x+1, y*2, z**2
print(func(3, 4, 5)) print(func(y=3, z=4, x=5))
# 默认参数:给参数指定默认值
def func(x=2, y=4, z=7):
return x+1, y*2, z**2
print(func()) print(func(2, 5)) print(func(2, 5, 8))
# 可变参数允许传入0个或多个参数,在函数调用时自动组装成一个元组
def func(x, y, *args):
print(args) return x+1, y*2 print(func(4, 5)) print(func(3, 5, 56, 23)) print(func(3, 5, [56, 23]))
# 关键字参数:允许传入0个或多个含参数名的参数,自动组装成一个字典,可以拓展函数的功能
def func(x, y, **kwargs):
print(kwargs) return x+1, y*2 print(func(4, 5)) print(func(3, 5, z=5, s=56))
def func(x, *args, **kwargs):
print(x)
print(args) print(kwargs) func(2, *[3, 5, 6], **{"name":"zhangsan"}) func(2, 3, 5, 6, y="34", z=34)
# 参数组合
def func(x, *args, **kwargs):
print(x) print(args) print(kwargs) func(2, *[3, 5, 6], **{"name":"zhangsan"}) func(2, 3, 5, 6, y="34", z=34)
4. 函数返回值
def func():
""" """
pass # 无返回值时默认返回 None
def func(x):
""" """
return x+1 # 一个返回值时返回对应的Object
def func(x):
""" """
return x+1, x*2, x**2 # 多个返回值时返回一个元组 print(func(3)) # (4, 6, 9)
5. 函数作用域
def func():
print("func") def func2(): print("func2") return func # 返回func在内存中的地址 res = func2() print(res) print(res())
二、局部变量和全局变量
name = "zhangsan" # 全局变量
def func(): # name = "lisi" # 局部变量:只在函数内部起作用 global name # 引入全局变量,若没有global,优先读取局部变量,没有则读全局变量(只能读,不能修改) name = "哈哈" func() print(name)
三、递归函数
在一个函数内部调用函数自身,则为递归函数。
特性:
(1)必须有一个明确的结束条件
(2)每进入一次递归,问题规模相比上一次都应该有所减少
(3)递归效率不高,递归层次过多会导致栈溢出
# 示例
def func(n):
print(n) if int(n/2) == 0: return n return func(int(n/2)) func(10)
四、匿名函数
func = lambda x: x+1 # 匿名函数:关键字lambda,x为形参,x+1为返回值
print(func(10))
func1 = lambda x, y: x if x > y else y print(func1(67, 3)) func2 = lambda x, y, z: (x+1, y*2, z**2) print(func2(7, 3, 4))
五、函数式编程
(1)不可变:不用变量保存状态,不修改变量(没有任何赋值操作)。
(2)第一类对象:函数即变量,函数名可以当做参数传递,也可以当做返回值。
(3)尾调用:在函数的最后一步调用另一个函数(最后一步不一定是最后一行)。
1. 高阶函数
高阶函数:一个函数接收另一个函数作为形参,或者一个函数把另一个函数当做返回值返回,那么这个函数就称为高阶函数。
def foo(n):
return n*2
def foo1(n):
print(n) foo1(foo(2)) # 把函数当做参数传递给另一个函数 def foo2(): return foo # 把函数当做返回值 n = foo2() print(n(3))
2. 装饰器
不修改函数源代码,且不修改函数调用方式的情况下,为函数增加功能,可用装饰器实现。装饰器 = 高阶函数 + 函数嵌套 + 闭包
# 装饰器
import time
def timer(func): def wapper(*args, **kwargs): start_time = time.time() func(*args, **kwargs) end_time = time.time() print("函数运行时长:%s" % (end_time - start_time)) return wapper @timer def test(): time.sleep(1) print("test 函数运行完毕") test()
# 给函数增加登录验证,并模拟session功能
user_info = [{"username": "admin", "password": "admin111"}, {"username": "lisi", "password": "123456"}, {"username": "wangwu", "password": "abc123456"}] login_info = {"username": None, "is_login": False} def auth(auth_type = "filedb"): def auth_func(func): def wapper(*args, **kwargs): print("认证类型:%s" % auth_type) # 可根据认证类型再添加其它功能 if login_info["username"] and login_info["is_login"]: res = func(*args, **kwargs) return res username = input("请输入用户名:").strip() password = input("请输入密码:").strip() for user in user_info: if username == user.get("username") and password == user.get("password"): login_info["username"] = username login_info["is_login"] = True res = func(*args, **kwargs) return res else: print("用户名或密码错误,请重新登陆!") return wapper return auth_func @auth(auth_type = "filedb") # 带参数的装饰器,需在原始装饰器外层再嵌套一层函数,并传入参数 def login(): print("这里是登录页面") @auth(auth_type = "my") def home(): print("%s,欢迎登陆" % login_info["username"]) @auth() def shopping_car(goos): print("%s,您的购物车里有:%s" % (login_info["username"], goos)) login() home() shopping_car(("苹果", "汽车", "玫瑰"))
六、常用内置函数
print(abs(-6)) # 求绝对值
print(all([34, 4, -1, 3])) # 判断可迭代对象的所有元素是否都为True print(bin(4)) # 返回整数的二进制 # 空、None、0 的bool值为false print(bool("")) print(bytes("你好", encoding="utf-8")) # 转换成字节 print(chr(98)) # 返回整数对应的字符 print(dict(a='a', b='b', t='t')) # 创建一个字典 # 把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b),可用于分页处理 print(divmod(10, 3)) # 用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标 print(list(enumerate(["苹果", "香蕉", "梨"]))) # 不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表 print(dir()) # 执行一个表达式,并返回结果;把字符串的表达式进行运算 print(eval('pow(2,3)')) print(eval("3+4*(6-2)")) print(hash('test')) # 获取一个对象(不可变数据类型)的hash值 # 将可迭代对象作为参数,组成一一对应的关系打包成元组,并返回由这些元组组成的迭代器对象 print(list(zip(("name", "age", "phone"), ("zhangsan", 45, "13333333333")))) dic = {'name': 'zhangsan', 'age': 45, 'phone': '13333333333'} print(list(zip(dic.keys(), dic.values()))) li = [3, 4, 6, 8] print(list(reversed(li))) print(list(sorted(li))) print(list(sorted(li, reverse=True)))
1. map()
根据提供的函数对指定序列做映射。
def square(n):
return n**2
res = map(square, [1, 2, 3, 4, 5])
for i in res: print(i, end=", ") print() res = map(lambda x:x**2, [1, 2, 3, 4, 5, 6]) print(list(res))
2. filter()
过滤序列,过滤掉不符合条件的元素,符合条件的元素组成一个新的列表返回(Python 2.7返回列表,Python3返回迭代器对象)。
def is_odd(n):
return n % 2 == 1
newlist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(list(newlist))
3. reduce()
from functools import reduce
# reduce() 在 Python3 已被移除到 functools 模块
def add(x, y) : # 两数相加 return x + y # 必须传入有两个参数的函数,将前两个元素的执行结果和第三个元素作为参数传递给函数 print(reduce(add, [1, 2, 3, 4, 5]))