跳到主要内容

函数

函数

定义, 调用函数

定义函数
def fun_name(args):
'''docstring'''

statement

return value
调用函数
fun_name(args)

函数参数类型

位置参数
  • 根据定义顺序。
def fun_name(arg_1, arg_2, arg_3):
'''docstring'''
statement

fun_name(arg_1, arg_2, arg_3)
关键字参数
  • 使用键值对形式,
  • 无视定义顺序。
def fun_name(arg_1, arg_2, arg_3):
'''docstring'''
statement

fun_name(arg_2 = value_2, arg_3 = value_3, arg_1 = value_1)
可变位置参数
  • 创建一个元组,
  • 储存任意数量位置参数,
def fun_name(arg_1, *args):
'''docstring'''
statement

fun_name(arg_1, arg_2, arg_3)
可变关键字参数
  • 创建一个字典,
  • 储存任意数量关键字参数,
def fun_name(arg_1, **kwargs):
'''docstring'''
statement

fun_name(arg_1, arg_2 = value_2, arg_3 = value_3)

函数参数默认值

参数默认值
  • 函数定义参数使用键值对形式,
  • 函数调用时该参数可选,
  • 若不指定值则使用默认值,
  • 反之使用指定值。
def fun_name(arg_1, arg_2, arg_3 = default_value):
'''docstring'''
statement

# arg_3 = default_value
fun_name(arg_1, arg_2 = value_2)
# arg_3 = value_3
fun_name(arg_1, arg_2 = value_2, arg_3 = value_3)

函数参数顺序

基本原则
  • 非默认参数在默认参数前面;
  • 位置参数可放置于任意位置 (除最后);
  • 关键字参数可放置于任意位置 (除最后),但其后函数参数调用必须使用键值对形式;
  • 可变位置参数可放置于任意位置 (除最后),但其后函数参数调用必须使用键值对形式;
  • 可变关键字参数必须放在最后;
一般原则
  • 位置参数,关键字参数,可变位置参数,可变关键字参数;
def fun_name(args, kwargs, *args, **kwargs):
'''docstring'''
statement

def fun_name(*args, kwargs, **kwargs):
'''docstring'''
statement

传参机制

函数传参机制
  • 引用传递;
  • 传参传递的为对象的内存地址;
  • 若函数参数为引用类型,函数内部的改变将引起对象自身的改变;
    • 列表;
    • 字典;
    • 集合;
预防方法
  • 传递对象自身副本。

匿名函数

使用匿名函数

匿名函数
# 普通函数
(lambda x, y: x+y)(2, 4) # 6

# if
(lambda x, y: x if x < y else y )( 1, 2 ) # 1

# 递归
func = lambda n:1 if n == 0 else n * func(n-1)
func(5) # 120

高阶函数

map 函数
map(lambda x: x*2, [1,2,3,4,5]) # [2, 4, 6, 8, 10]
filter 函数
filter(lambda x: x < 0, range(-5, 5)) # [-5, -4, -3, -2, -1]
reduce 函数
reduce(lambda x,y: x+y, [1,2,3,4,5]) # 15
map 函数

闭包

闭包
  • 内部函数引用外部函数变量;
  • 导致外部函数无法即使垃圾回收;
def deco():
name = "MING"
def wrapper():
print(name)
return wrapper

deco()() # MING
python 闭包的局限
  • 闭包只能引用外部函数变量;
  • 但无法对其进行操作,否则报错;

泛型

泛型
  • 导入 singledispatch;
  • 使用 @singledispatch 和 @fun.register 装饰器;
from functools import singledispatch

@singledispatch
def age(obj):
print('error')

@age.register(int)
def _(age):
print('int')

@age.register(str)
def _(age):
print('str')

age(23) # int
age('twenty three') # str
age(['23']) # error

装饰器

装饰器
  • 本质是一个函数;
  • 在不改变其它函数代码的情况下添加额外功能;
定义和使用装饰器
  • 定义装饰器:接受一个目标函数并返回一个函数;
  • 使用装饰器:使用 @func;
## 定义装饰器
def decorator(func):
def wrapper(*args, **kw):
return func()
return wrapper

## 使用装饰器
@decorator
def function():
print("hello, decorator")
普通函数装饰器
# 这是装饰器函数, 参数 func 是被装饰的函数
def logger(func):
def wrapper(*args, **kw):
print('我准备开始执行: {} 函数了:'.format(func.__name__))

# 真正执行的是这行.
func(*args, **kw)

print('主人, 我执行完啦. ')
return wrapper

@logger
def add(x, y):
print('{} + {} = {}'.format(x, y, x+y))

# 我准备开始执行: add 函数了:
# 200 + 50 = 250
# 我执行完啦.
add(200, 50)
带参数的函数装饰器
  • 需要两层嵌套;
def say_hello(contry):
def wrapper(func):
def deco(*args, **kwargs):
if contry == "china":
print("你好!")
elif contry == "america":
print('hello.')
else:
return

func(*args, **kwargs)

return deco

return wrapper

@say_hello("china")
def xiaoming():
pass

@say_hello("america")
def jack():
pass

xiaoming() # 你好
jack() # hello

python 内置函数

type() 函数
  • type(object)。
    • 返回 object 类型;
    • object:判断对象;
    • 返回值:对象类型;
id() 函数
  • 返回对象的唯一标识符;
a = "hello"
id(a) # 4470767944
isinstance() 函数
  • 确定对象是否是某类型或类的实例;
isinstance("python", str) # True
isinstance(10, int) # True
  • print(*objects,sep=' ',end='\n')。
    • 打印多个对象。
    • objects:对象;
    • sep:间隔多个对象,默认为 None;
    • end:对象末尾添加符,默认为 '\n'。
    • 返回值:str。
>>> people = 'kxh\'s age'
>>> age = '25'
>>> print(people, age, sep=' : ', end='?\n')
kxh's age : 25?
input() 函数
  • input([prompt])。
    • 接受输入数据;
    • prompt:提示信息;
    • 返回值:str。
>>> name = input('please enter your name.\n')
please enter your name.
kxh
>>> print(name)
kxh
>>> type(name)
<class 'str'>