Python语言中的函数和模块是代码组织和复用的重要机制:
一、函数 (Function)
函数是一组为了实现特定功能的代码块,可以被重复调用。
1. 函数的定义与调用
# 定义函数
def greet(name):
"""这是函数的文档字符串(docstring)"""
print(f"Hello, {name}!")
# 调用函数
greet("Alice") # 输出: Hello, Alice!
2. 函数的参数
2.1 位置参数
def add(a, b):
return a + b
result = add(3, 5) # 8
2.2 关键字参数
def person(name, age):
print(f"Name: {name}, Age: {age}")
person(name="Bob", age=25) # 按名称传递
person(age=30, name="Charlie") # 可以改变顺序
2.3 默认参数
def greet(name, message="Hello"):
print(f"{message}, {name}!")
greet("Alice") # Hello, Alice!
greet("Bob", "Hi") # Hi, Bob!
2.4 可变参数
def sum_numbers(*args): # args是元组
return sum(args)
result = sum_numbers(1, 2, 3, 4, 5) # 15
2.5 关键字可变参数
def print_info(**kwargs): # kwargs是字典
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="Alice", age=25, city="New York")
3. 函数的返回值
def multiply(a, b):
return a * b
result = multiply(3, 5) # 15
# 返回多个值
def get_person():
return "Alice", 25, "New York"
name, age, city = get_person()
4. 作用域
局部变量 :在函数内部定义的变量,只在函数内部有效
全局变量 :在函数外部定义的变量,在整个程序中有效
nonlocal变量 :在嵌套函数中使用的外部函数变量
# 全局变量
global_var = "I'm global"
def outer_func():
# 局部变量
local_var = "I'm local"
def inner_func():
nonlocal local_var # 使用外部函数的变量
local_var = "Modified local"
print(local_var)
inner_func()
print(local_var) # Modified local
print(global_var)
outer_func()
# print(local_var) # 会报错
5. 匿名函数 (Lambda)
# 基本语法: lambda 参数: 表达式
square = lambda x: x ** 2
print(square(5)) # 25
# 与内置函数结合使用
numbers = [1, 2, 3, 4, 5]
squares = list(map(lambda x: x ** 2, numbers)) # [1, 4, 9, 16, 25]
even_numbers = list(filter(lambda x: x % 2 == 0, numbers)) # [2, 4]
6. 装饰器
用于修改函数的功能,而不改变函数的代码:
def decorator(func):
def wrapper(*args, **kwargs):
print("Before function call")
result = func(*args, **kwargs)
print("After function call")
return result
return wrapper
@decorator
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
# 输出:
# Before function call
# Hello, Alice!
# After function call
二、模块 (Module)
模块是一个包含Python代码的文件,扩展名为 .py ,用于组织代码。
1. 创建模块
创建一个名为 mymodule.py 的文件:
# mymodule.py
PI = 3.14159
def calculate_area(radius):
return PI * radius ** 2
def calculate_circumference(radius):
return 2 * PI * radius
2. 导入模块
2.1 导入整个模块
import mymodule
print(mymodule.PI) # 3.14159
area = mymodule.calculate_area(5) # 78.53975
2.2 导入特定函数
from mymodule import calculate_area, calculate_circumference
area = calculate_area(5) # 78.53975
circumference = calculate_circumference(5) # 31.4159
2.3 导入所有函数
from mymodule import * # 不推荐,可能导致命名冲突
print(PI)
area = calculate_area(5)
2.4 使用别名
import mymodule as mm
print(mm.PI)
area = mm.calculate_area(5)
from mymodule import calculate_area as ca
area = ca(5)
3. 标准库模块
Python提供了丰富的标准库模块:
# 数学模块
import math
print(math.sqrt(16)) # 4.0
print(math.pi) # 3.141592653589793
# 随机模块
import random
print(random.randint(1, 10)) # 1-10之间的随机整数
print(random.choice(["apple", "banana", "cherry"])) # 随机选择元素
# 时间模块
import time
print(time.time()) # 时间戳
print(time.strftime("%Y-%m-%d %H:%M:%S")) # 格式化时间
# 文件操作
import os
print(os.getcwd()) # 当前工作目录
print(os.listdir()) # 列出目录内容
4. 包 (Package)
包是一个包含多个模块的目录,必须包含一个 init.py 文件(可以为空)。
目录结构:
mypackage/
├── init.py
├── module1.py
└── module2.py
导入包中的模块 :
# 方式1
import mypackage.module1
mypackage.module1.function1()
# 方式2
from mypackage import module2
module2.function2()
# 方式3
from mypackage.module1 import function1
function1()
5. init.py 文件
可以在 init.py 中定义包的初始化代码:
# mypackage/__init__.py
from .module1 import function1
from .module2 import function2
__version__ = "1.0.0"
这样可以直接从包中导入函数:
from mypackage import function1, function2
print(mypackage.__version__)
6. 相对导入
在包内部使用相对导入:
# 在mypackage/module1.py中
from . import module2 # 同一包中的模块
from .. import other_package # 父包中的模块
特别说明
当你在 init.py 文件中导入子模块的内容时,这些内容会成为包的直接属性,其他代码导入这个包时就能直接访问这些内容。
具体示例:
- 创建包结构
mypackage/
├── init.py
├── module1.py
└── module2.py
- 子模块内容
module1.py
def function1():
return "This is function1 from module1"
class Class1:
def init(self):
self.name = "Class1"
module2.py
def function2():
return "This is function2 from module2"
class Class2:
def init(self):
self.name = "Class2"
- 在__init__.py中导入
init.py
导入子模块的函数和类
from .module1 import function1, Class1
from .module2 import function2, Class2
定义包的版本
version = "1.0.0"
可以只导入模块
from . import module1
from . import module2
- 使用包的两种方式
方式一:直接从包中导入(推荐)
其他Python文件
from mypackage import function1, Class1
from mypackage import function2, Class2
使用导入的函数和类
print(function1()) # This is function1 from module1
obj1 = Class1()
print(obj1.name) # Class1
print(function2()) # This is function2 from module2
obj2 = Class2()
print(obj2.name) # Class2
访问包版本
import mypackage
print(mypackage.version) # 1.0.0
方式二:通过模块导入
也可以这样使用(不推荐,因为更复杂)
from mypackage.module1 import function1
from mypackage.module2 import Class2
print(function1())
obj2 = Class2()
优点:
简化导入语句 :用户不需要记住具体的子模块路径
隐藏内部结构 :可以将包的内部结构(如模块划分)与外部接口分离
统一接口 :提供一致的导入方式,即使内部结构发生变化也不影响外部使用
注意事项:不要滥用这种方式,只导入最常用的功能
如果导入的内容太多,可能会导致命名冲突
要保持 init.py 的简洁,避免在其中添加复杂的逻辑
可以在 init.py 中使用 all 变量来控制 from package import * 时导入的内容:
init.py
from .module1 import function1, Class1
from .module2 import function2, Class2
all = ['function1', 'Class1', 'function2', 'Class2']
三、面试题目
题目 1:选择题
以下哪个是Python中定义函数的正确语法?
A. def function_name[]
B. function function_name()
C. def function_name():
D. function_name def()
答案:C. def function_name():解析:Python定义函数需使用def关键字 + 函数名 + 括号 + 冒号,如def add(a, b):。
题目 2:编程题
请编写一个Python函数,接收两个整数参数,返回它们的和,并在主程序中调用该函数。
def add_numbers(a, b):
return a + bresult = add_numbers(3, 5)
print(f"3 + 5 = {result}")
# 输出:3 + 5 = 8
题目 3:填空题
在Python中,函数的返回值使用______关键字来返回。
函数的参数可以有默认值,如果在调用函数时没有传入该参数的值,则会使用______的默认值。
第一个空:return第二个空:定义时设定的默认值
题目 4:编程题
编写一个Python函数,接收一个字符串参数,判断该字符串是否是回文(即正读和反读都相同的字符串),如果是回文,返回True,否则返回False。
示例:
输入:"madam"
输出:True
def is_palindrome(s):
return s == s[::-1]
# 通过反转字符串比较
print(is_palindrome("madam"))
# 输出:True
题目 5:选择题
以下哪个是Python中函数参数的正确用法?
A. 可以通过位置传递参数,也可以通过关键字传递参数
B. 函数参数只能通过位置传递
C. 函数参数只能通过关键字传递
D. Python中函数不支持参数传递
答案:A. 可以通过位置传递参数,也可以通过关键字传递参数
题目 6:编程题
编写一个Python函数,接收一个整数列表,并返回该列表中所有奇数的平方值组成的新列表。
示例:
输入:[1, 2, 3, 4, 5]
输出:[1, 9, 25]
def square_odds(numbers):
return [x**2 for x in numbers if x % 2 != 0]
print(square_odds([1, 2, 3, 4, 5]))
# 输出:[1, 9, 25]
题目 7:选择题
在Python中,函数的参数如果有默认值,则:
A. 必须在没有默认值的参数之后
B. 必须在没有默认值的参数之前
C. 默认值参数不能有
D. 没有参数顺序的要求
答案:A. 必须在没有默认值的参数之后错误示例:def func(a=1, b): → 语法错误,必须将b放在a前。
题目 8:简答题
简要说明Python中全局变量和局部变量的区别,并举例说明函数内如何使用它们。
全局变量:在函数外部定义,所有函数均可访问。修改需用global声明。局部变量:在函数内部定义,函数执行结束后销毁。
题目 9:编程题
编写一个Python程序,定义一个函数,该函数能够接收任意数量的位置参数并输出它们的和。函数使用*args来接受多个位置参数。
示例:
输入:sum_of_numbers(1, 2, 3, 4)
输出:10
def sum_of_numbers(*args):
return sum(args)
# *args接收任意位置参数
print(sum_of_numbers(1, 2, 3, 4))
# 输出:10
题目 10:选择题
以下哪个语句可以用来导入一个Python模块?
A. import module_name
B. from module_name import function_name
C. import module_name as alias
D. 以上三者都是有效的导入方式
D. 以上三者都是有效的导入方式