函数
函数就是组织好的, 可以重复使用的, 用于是想特定功能的代码片段, 比如之前学的 print input range type
等, 但是那些都是编译器内置的函数 而我们现在要学习的是自定义的函数
定义与调用
python
# - 定义
def 函数名(参数 1, 参数 2...参数 n)
"""
函数说明文档(可选)
"""
函数体代码
return 结果
# - 调用
变量接收结果=函数名(参数 1, 参数 2...参数 n)
python
# 定义函数(获取字符串中字符的个数)
def length(s):
"""
获取一个字符串的长度
:param s: 字符串
:return : 字符串长度
"""
char_count = 0
for i in s:
char_count += 1
return char_count
# 调用函数
print(length("tom")) # 3
print(length("hello")) # 5
None 类型
空值, 类似 js 的 undefined
python
def say_hi():
print("hi")
res = say_hi()
print(res) # None
作用域
变量的作用范围, 简单来说就是在哪个位置可以访问, 哪个位置不能访问
全局作用域
python
msg = "hi"
def f1():
# 在函数 1 中可以访问
print(msg)
def f2():
# 在函数 2 中可以访问
print(msg)
# 在函数外部也能使用
print(msg)
f1()
f1()
函数作用域
python
def f1():
# 只能在函数内部使用
msg = "hi"
print(msg)
f1()
# print(msg)
# 无法在函数外部使用
# NameError: name 'msg' is not defined
global
为什么输出 hi
而不是 hello
?
python
msg = "hi"
def f1():
# 因为这个 msg 是局部变量和外部的 msg 没有关系
msg = "hello"
print(msg)
f1()
print(msg)
现在, 我就是想要在 f1 函数中修改 msg 的值, 应该如何操作?
python
msg = "hi"
def f1():
# 告诉编译器 num 是全局变量不是函数内部的局部变量
global num
msg = "hello" # 此时就可以正常修改 msg 的值
print(msg)
f1()
# 输出 hello
print(msg)
函数多返回值
python
def ret_mut_items():
return 1, 2, 3
items = ret_mut_items()
print(type(items)) # <class 'tuple'>
# 类似 js 中的解构操作
a, b, c = ret_mut_items()
print(type(a), type(b), type(c))
# <class 'int'> <class 'int'> <class 'int'>
函数默认参数
与 js 的默认参数一模一样, 注意有默认值的放最后
py
def get_conf(url="http://localhost", port="8080"):
return url, port
url1, port1 = get_conf(url="http://example.com", port="80")
url2, port2 = get_conf()
print(f"url1: {url1}")
print(f"url2: {url2}")
print(f"port1: {port1}")
print(f"port2: {port2}")
# Console Output:
# url1: http://example.com
# url2: http://localhost
# port1: 80
# port2: 8080
函数可变参数
- *:
位置不定长参数
, 任意多个参数, 组成 tuple 供函数内部访问 - **
关键字不定长参数
, 任意多个参数但必须是 key value 对, 组成字典供函数内部访问
python
# 类似 js 的剩余参数 `output_args(...args)`
def output_args1(*args):
print(args) # (1,2,3,4,5)
print(type(args)) # tuple
output_args1(1, 2, 3, 4, 5)
def output_args2(**kwargs):
print(kwargs)
# 必须传入字典的函数
output_args2(id=1, name="tom", gender="male")
lambda 匿名函数
- 注意: 函数体只能写一行
python
items = [1, 3, 5, 7, 9]
def for_each_list(items, handler):
for i in range(len(items)):
item = items[i]
handler(i, item)
# 类似 js 箭头函数 (x, y) => xxx, 但是 lambda 只能写一行
# lambda 参数1, 参数2 : 函数体(一行)
for_each_list(items, lambda i, n: print(f"index:{i} value:{n}"))
闭包
python
# 函数缓存
def memoize(fn):
caches = {}
def memoized_func(*args):
nonlocal caches # 这个 caches 会一直被引用不会释放
key = f"{args}"
cache = caches.get(key)
if(cache):
print("result from cache")
return cache
else:
val = fn(*args)
caches[key] = val
return val
return memoized_func
def sum(x, y):
print(f"sum is called with {x},{y}")
return x + y
lazy_sum = memoize(sum)
lazy_sum(1, 2)
lazy_sum(1, 2)
lazy_sum(1, 2)
lazy_sum(1, 2)
lazy_sum(1, 2)
lazy_sum(3, 4)
lazy_sum(3, 4)
lazy_sum(3, 4)
lazy_sum(3, 4)
lazy_sum(3, 4)
lazy_sum(3, 4)