文章目录
一、函数
函数是Python中组织代码的基本单位。它可以通过封装一组语句,实现代码复用。函数可以接受输入参数并返回结果,极大地提高了代码的可读性和维护性。
1. 定义函数
在Python中,使用def
关键字来定义一个函数。函数名后面跟一对小括号,括号中可以放参数。函数体需要缩进。
1.1 基本函数定义
def greet():
print("Hello, World!")
# 调用函数
greet() # 输出: Hello, World!
1.2 带参数的函数
函数可以接受输入的参数,定义时在括号中列出参数名,调用时传入相应的值。
def greet(name):
print(f"Hello, {name}!")
greet("Alice") # 输出: Hello, Alice!
1.3 带返回值的函数
函数可以返回一个值,使用return
语句返回结果。如果没有return
语句,函数默认返回None
。
def add(a, b):
return a + b
result = add(3, 4)
print(result) # 输出: 7
2. 参数传递
Python支持多种类型的参数传递方式。函数定义时可以使用位置参数、默认参数、可变参数和关键字参数等。
2.1 位置参数
位置参数是最常见的参数传递方式,调用时必须按照定义的顺序传入值。
def subtract(a, b):
return a - b
print(subtract(10, 5)) # 输出: 5
2.2 默认参数
函数定义时可以为某些参数设置默认值。调用时可以选择传入该参数的值,也可以使用默认值。
def greet(name="Guest"):
print(f"Hello, {name}!")
greet("Alice") # 输出: Hello, Alice!
greet() # 输出: Hello, Guest!
2.3 可变参数
如果不确定函数需要接收多少个参数,可以使用可变参数。Python提供了两种方式来处理可变参数:
*args
:用于接收位置参数,收集传入的多个位置参数并将它们作为元组传递。**kwargs
:用于接收关键字参数,收集传入的多个关键字参数并将它们作为字典传递。
2.3.1 使用*args
def sum_numbers(*args):
return sum(args)
print(sum_numbers(1, 2, 3)) # 输出: 6
print(sum_numbers(1, 2, 3, 4, 5)) # 输出: 15
2.3.2 使用**kwargs
def display_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
display_info(name="Alice", age=25)
# 输出:
# name: Alice
# age: 25
2.4 参数的混合使用
可以混合使用位置参数、默认参数、*args
和**kwargs
,但需要遵循一定的顺序:位置参数 > 默认参数 > *args
> **kwargs
。
def greet(name, age=30, *args, **kwargs):
print(f"Name: {name}, Age: {age}")
print("Additional Arguments:", args)
print("Keyword Arguments:", kwargs)
greet("Alice", 25, "Engineer", country="USA", hobby="Reading")
# 输出:
# Name: Alice, Age: 25
# Additional Arguments: ('Engineer',)
# Keyword Arguments: {'country': 'USA', 'hobby': 'Reading'}
3. 作用域
Python中的作用域是指变量的可访问范围。作用域主要分为四种:
- 局部作用域(Local Scope):函数内部定义的变量,只在函数内部有效。
- 嵌套作用域(Enclosing Scope):嵌套函数中的外部函数作用域。
- 全局作用域(Global Scope):在模块级别定义的变量,可以在整个模块内访问。
- 内置作用域(Built-in Scope):Python内置的标识符,如
print()
、len()
等。
Python根据作用域规则来查找变量,遵循LEGB(Local -> Enclosing -> Global -> Built-in)规则。
3.1 局部和全局变量
x = 10 # 全局变量
def example():
x = 5 # 局部变量
print("Local x:", x)
example() # 输出: Local x: 5
print("Global x:", x) # 输出: Global x: 10
好的,我将详细解释global
和nonlocal
关键字的工作原理,并提供更详细的案例。
3.2 global
关键字
global
关键字用于在函数内部声明变量为全局变量。这意味着在函数内部修改该变量的值时,修改的是全局作用域中的变量,而不是局部作用域中的新变量。
案例:修改全局变量
假设我们有一个全局变量x
,我们想要在一个函数内部修改它的值。没有global
关键字的话,Python会认为我们在函数内部创建了一个局部变量,而不会影响全局变量。为了确保修改全局变量,必须使用global
关键字。
# 全局变量 x
x = 10
# 定义一个函数来修改 x
def modify_global():
global x # 声明x为全局变量
print(f"修改前的全局变量 x: {x}") # 输出全局变量x的值
x = 20 # 修改全局变量 x
print(f"修改后的全局变量 x: {x}") # 输出修改后的值
# 调用函数
modify_global()
# 输出全局变量 x 的最终值
print(f"全局变量 x 在函数外部的值: {x}")
输出:
修改前的全局变量 x: 10
修改后的全局变量 x: 20
全局变量 x 在函数外部的值: 20
解释:
- 在
modify_global
函数内部,通过global x
声明了x
是全局变量,所以我们可以修改全局作用域中的x
。 - 在函数内修改
x
的值时,实际上修改的是全局变量,而不是在函数内创建一个新的局部变量。 - 函数调用后,
x
的值已经改变,打印出的x
的值为20
,这就是全局作用域中变量的最新值。
3.3 nonlocal
关键字
nonlocal
关键字用于在嵌套函数中修改外部函数的局部变量,而不是全局变量。它会查找最靠近的外层作用域,确保修改的是外层函数的局部变量,而不是在当前函数或全局作用域中创建新变量。
案例:修改外部函数的局部变量
假设我们有一个外部函数outer
,其中定义了一个变量x
,并且有一个嵌套的内部函数inner
。如果我们希望在inner
函数中修改outer
函数中的x
,就需要使用nonlocal
关键字。
def outer():
x = 10 # 外部函数中的局部变量
print(f"外部函数 outer 中的初始 x: {x}") # 输出初始值
def inner():
nonlocal x # 使用 nonlocal 修改外部函数中的 x
print(f"内层函数 inner 中的 x(修改前): {x}") # 输出修改前的值
x = 20 # 修改外部函数中的 x
print(f"内层函数 inner 中的 x(修改后): {x}") # 输出修改后的值
inner() # 调用内层函数
print(f"外部函数 outer 中的 x(修改后): {x}") # 输出外部函数中的最终值
# 调用外部函数
outer()
输出:
外部函数 outer 中的初始 x: 10
内层函数 inner 中的 x(修改前): 10
内层函数 inner 中的 x(修改后): 20
外部函数 outer 中的 x(修改后): 20
解释:
outer
函数中定义了变量x
,初始值为10
。- 在
inner
函数中,通过nonlocal x
声明x
是outer
函数中的局部变量。这使得inner
函数中的x
指向outer
函数的x
,而不是在inner
中创建一个新的局部变量。 - 在
inner
函数中修改了x
的值为20
,这直接影响了外部函数outer
中的x
。 - 最终,
outer
函数中的x
的值变为20
。
总结:
global
:用于声明在函数内修改全局变量。nonlocal
:用于声明在嵌套函数中修改外部函数的局部变量,而不是创建一个新的局部变量。
4. lambda 表达式
Lambda表达式是Python中创建匿名函数的一种方式。它通常用于简化函数定义,特别是在需要传递函数作为参数的场合。
4.1 基本用法
# 定义一个简单的lambda函数
add = lambda x, y: x + y
print(add(2, 3)) # 输出: 5
4.2 与map()
、filter()
和sorted()
结合使用
lambda
表达式常常与Python的内置函数map()
、filter()
和sorted()
一起使用,以简化代码。
map()
:将函数应用到序列的每个元素上。filter()
:过滤掉不满足条件的元素。sorted()
:根据指定的排序规则对序列进行排序。
# 使用lambda和map
numbers = [1, 2, 3, 4]
squared = list(map(lambda x: x**2, numbers))
print(squared) # 输出: [1, 4, 9, 16]
# 使用lambda和filter
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers) # 输出: [2, 4]
# 使用lambda和sorted
sorted_numbers = sorted(numbers, key=lambda x: -x)
print(sorted_numbers) # 输出: [4, 3, 2, 1]
5. 常用内置函数
Python提供了大量的内置函数,这些函数可以帮助我们进行常见的操作,如数据转换、数学计算、序列操作等。
5.1 数据类型转换
int()
:将字符串或其他数字类型转换为整数。float()
:将字符串或其他数字类型转换为浮点数。str()
:将对象转换为字符串。
x = "123"
print(int(x)) # 输出: 123
print(float(x)) # 输出: 123.0
print(str(123)) # 输出: '123'
5.2 数学函数
abs()
:返回绝对值。min()
:返回最小值。max()
:返回最大值。sum()
:返回序列中所有元素的和。
print(abs(-10)) # 输出: 10
print(min(1, 2, 3)) # 输出: 1
print(max(1, 2, 3)) # 输出: 3
print(sum([1, 2, 3])) # 输出: 6
5.3 序列操作
len()
:返回序列的长度。sorted()
:返回排序后的序列。reversed()
:返回反转后的序列。
a = [3, 1, 2]
print(len(a)) # 输出: 3
print(sorted(a)) # 输出: [1, 2, 3]
print(list(reversed(a))) # 输出: [2, 1, 3]
5.4 其他常用函数
enumerate()
:返回一个枚举对象,可以同时获取序列的索引和值。zip()
:将多个可迭代对象打包成一个元组的列表。all()
:如果所有元素为True
,返回True
。any()
:如果至少一个元素为True
,返回True
。
a = ['apple', 'banana', 'cherry']
for idx, fruit in enumerate(a):
print(idx, fruit)
b = [1, 2, 3]
c = ['a', 'b', 'c']
zipped = list(zip(b, c))
print(zipped) # 输出: [(1, 'a'), (2, 'b'), (3, 'c')]
print(all([True, True, False])) # 输出: False
print(any([False, False, True])) # 输出: True