# 函数和模块
代码有很多种坏味道,重复是最坏的一种。
要写出高质量的代码首先要解决的就是重复代码的问题。
# 函数相关
# 函数的定义
在 python 中,使用关键字 def
定义函数。它由函数名,参数,函数主题组成。
每一个函数都有一个响亮的名字,但通常和变量名一样,见名识意。
函数的参数叫形参
函数一般通过
return
关键字返回一个值。
def greet(name):
"""这个函数会打印一条包含传入名字的问候语。"""
print(f"Hello, {name}!")
# 调用函数
greet("World") # 输出: Hello, World!
greet("Python") # 输出: Hello, Python!
函数定义后面的三引号括起来的内容是函数的文档字符串,用于解释函数的功能和用法。
# 函数的参数
在 python 中,参数是函数定义中的一部分,用于接收传递给函数的值,参数定义了函数期望接收的数据类型和数量。当你调用函数时,传递给函数的值成为实参。
# 参数的类型
- 位置参数:数定义中的参数按照从左到右的顺序排列,并在调用函数时按照同样的顺序传递值。
def greet(name, age):
print(f"Hello, {name}. You are {age} years old.")
greet("Alice", 30) # 正确调用,按照位置传递参数
关键字参数:在调用函数时,你可以通过参数名(关键字)来指定参数的值。这允许你以任意顺序传递参数,只要确保每个参数名都与其对应的值匹配。
默认参数:在函数定义中,可以为参数指定默认值。如果调用函数时没有提供该参数的值,则使用默认值。
可变位置参数:使用
*args
语法,可以允许函数接收任意数量的位置参数,并将它们作为元组处理。
def print_numbers(*numbers):
for num in numbers:
print(num)
print_numbers(1, 2, 3, 4) # 输出 1 2 3 4
- 可变关键字参数:使用
**kwargs
语法,可以允许函数接收任意数量的关键字参数,并将它们作为字典处理。
def print_info(**info):
for key, value in info.items():
print(f"{key}: {value}")
print_info(name="Alice", age=30) # 输出 name: Alice 和 age: 30
# 模块相关
在 python 中,每个文件就代表了一个模块,模块可以定义函数,类,变量。然后这些定义可以被其他程序或模块导入和使用。模块是组织代码的一种方式,有助于代码重用,避免命名冲突,提高代码的可维护性。
代码重用:其他程序可以通过关键字
import
来导入模块中的函数,类或者变量。命名空间:有助于避免命名冲突。
组织代码:将相关的代码组织在一起,易于阅读和维护。
可扩展性:方便添加新功能,并在需要的时候导入到主程序即可。
导入方式:可以使用关键字
import
导入整个模块,使用from ... import ...
语句导入模块中的特定函数,类,或者变量。
# 导入方式
1、导入整个模块
使用模块中的函数时,需要加上模块名作为前缀。
import math
result = math.sqrt(16)
print(result)
2、从模块中导入特定的函数或者变量
在使用时,直接使用函数名,不需要加模块名前缀
from math import sqrt
result = sqrt(16)
print(result)
3、从模块中导入多个特定的函数或变量
在使用时,直接使用函数名,不需要加模块名前缀
from math import sqrt,pow
# 直接使用函数名
result1 = sqrt(16)
result2 = pow(2, 3)
print(result1) # 输出: 4.0
print(result2) # 输出: 8.0
4、导入模块并使用别名 as
关键字
使用别名作为模块名前缀
import math as m
result = m.sqrt(16)
print(result) # 输出: 4.0
5、从模块中导入所有内容(通常不推荐,因为可能导致命名冲突)
from math import *
result1 = sqrt(16)
print(result1) # 输出: 4.0
尽管使用 from module import *
可以避免在代码中频繁地写模块名前缀,但这通常不是一个好的编程习惯,因为它可能会导致命名冲突和难以追踪的依赖关系。在大型项目中,最好明确地从模块中导入你需要的函数或变量。
另外,如果导入的模块除了定义函数之外,还有可执行的代码,那么 python 解释器在导入这个模块时就会执行这些代码,如果想要在导入模块的时候不执行这些代码,可以在模块中将这些执行代码放到入口中:
if __name__ == '__main__':
.
.
.
# 变量的作用域
# 局部作用域
在函数或方法内部定义的变量具有局部作用域。这意味着这些变量只能在函数或方法内部被访问。
当函数或方法执行完毕后,这些变量就会被销毁(除非它们被作为返回值或通过某种方式传递到外部作用域)。
# 嵌套作用域
如果一个函数内部定义了另一个函数,那么内部函数可以访问外部函数的变量(除了那些被标记为nonlocal或global的)。
# 全局作用域
在所有函数和方法之外定义的变量具有全局作用域。这意味着这些变量可以在整个程序中被访问。
在函数内部,你可以通过global关键字来声明一个变量是全局的,从而可以在函数内部修改它。
# 内置作用域
内置作用域是Python解释器在启动时创建的,它包含了所有内置函数和异常的名字。
我们不能在这个作用域中定义新的变量,也不能删除这个作用域中的变量。
例如,len(), int(), True, False, 和 None 等都是内置作用域中的变量。