函数

基本理论

函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
函数内容以冒号 : 起始,并且缩进。
return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回 None。

代码展示

1
2
3
4
def hello() :
print("Hello World!")

hello()

参数

传值与传址

在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。
不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变 a 的值,相当于新生成了 a。
可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
python 函数的参数传递:
不可变类型:类似 C++ 的值传递,如整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身。如果在 fun(a) 内部修改 a 的值,则是新生成一个 a 的对象。
可变类型:类似 C++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后 fun 外部的 la 也会受影响
python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。

关键字参数

可以显式指定一个函数的参数

1
2
3
4
5
6
def printme( str1 , str2 ):
print (str1 + str2)
return

#调用printme函数
printme( str2="world" , str1 = "hello")

默认参数

可以给参数指定默认值

1
2
3
4
5
6
7
8
9
def printinfo( name, age = 35 ):
print ("名字: ", name)
print ("年龄: ", age)
return

#调用printinfo函数
printinfo( age=50, name="runoob" )
print ("------------------------")
printinfo( name="runoob" )

不定长参数

python中如果不指定默认值,则不定长参数是一个空元组。

1
2
3
def doSth(*words):
print(words)
doSth(1,2,3,4,5)

加了两个星号 ** 的参数会以字典的形式导入。

1
2
3
4
5
6
7
def printinfo( arg1, **vardict ):
print ("输出: ")
print (arg1)
print (vardict)

# 调用printinfo 函数
printinfo(1, a=2,b=3)

对比一下别的语言:

1
2
3
public void DoSth(params string[] words) {
......
}
1
2
3
function doSth(...params){
......
}

函数作用域

函数内部的变量和全局的变量不是一个,所以如果想在函数内部去修改一个全局变量通过一下写法不会生效:

1
2
3
4
5
6
a=10
def doSth():
a = 100
print(a) #100
doSth()
print(a) #10

可以使用global来修改全局变量:

1
2
3
4
5
6
7
a=10
def doSth():
global a
a=100
print(a) #100
doSth()
print(a) #100

匿名函数(lambda表达式)

基本理论

Python 使用 lambda 来创建匿名函数。
lambda 函数是一种小型、匿名的、内联函数,它可以具有任意数量的参数,但只能有一个表达式。
匿名函数不需要使用 def 关键字定义完整函数。
lambda 函数通常用于编写简单的、单行的函数,通常在需要函数作为参数传递的情况下使用,例如在 map()、filter()、reduce() 等函数中。
lambda 函数特点:
lambda 函数是匿名的,它们没有函数名称,只能通过赋值给变量或作为参数传递给其他函数来使用。
lambda 函数通常只包含一行代码,这使得它们适用于编写简单的函数。

代码展示

1
2
f = lambda: "Hello, world!"
print(f()) # 输出: Hello, world!
1
2
3
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
print(squared) # 输出: [1, 4, 9, 16, 25]
1
2
3
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers) # 输出:[2, 4, 6, 8]
1
2
3
4
5
from functools import reduce
numbers = [1, 2, 3, 4, 5]
# 使用 reduce() 和 lambda 函数计算乘积
product = reduce(lambda x, y: x * y, numbers)
print(product) # 输出:120

装饰器

基本理论

装饰器(decorators)是 Python 中的一种高级功能,它允许你动态地修改函数或类的行为。
装饰器是一种函数,它接受一个函数作为参数,并返回一个新的函数或修改原来的函数。
装饰器的语法使用 @decorator_name 来应用在函数或方法上。
Python 还提供了一些内置的装饰器,比如 @staticmethod 和 @classmethod,用于定义静态方法和类方法。
装饰器的应用场景:
日志记录: 装饰器可用于记录函数的调用信息、参数和返回值。
性能分析: 可以使用装饰器来测量函数的执行时间。
权限控制: 装饰器可用于限制对某些函数的访问权限。
缓存: 装饰器可用于实现函数结果的缓存,以提高性能。

代码展示

Python 装饰允许在不修改原有函数代码的基础上,动态地增加或修改函数的功能,装饰器本质上是一个接收函数作为输入并返回一个新的包装过后的函数的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def decorator_function(original_function):
def wrapper(*args, **kwargs):
# 这里是在调用原始函数前添加的新功能
print("函數執行前")

result = original_function(*args, **kwargs)

# 这里是在调用原始函数后添加的新功能
print("函數執行後")

return result

return wrapper


# 使用装饰器
@decorator_function
def target_function(arg1, arg2):
print(arg1)
print(arg2)
target_function('你好','世界')

带参数的装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def repeat(n):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(n):
result = func(*args, **kwargs)
return result
return wrapper
return decorator

@repeat(3)
def greet(name):
print(f"Hello, {name}!")

greet("Alice")

类装饰器

除了函数装饰器,Python 还支持类装饰器。类装饰器是包含 _call_ 方法的类,它接受一个函数作为参数,并返回一个新的函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
class DecoratorClass:
def __init__(self, func):
self.func = func

def __call__(self, *args, **kwargs):
# 在调用原始函数之前/之后执行的代码
result = self.func(*args, **kwargs)
# 在调用原始函数之后执行的代码
return result

@DecoratorClass
def my_function():
pass