目录
[3.1.单前导下划线 _var](#3.1.单前导下划线 _var)
[3.2.单后导下划线 var_](#3.2.单后导下划线 var_)
[3.3.双前导下划线 __var](#3.3.双前导下划线 __var)
[3.4.双前导和双后导下划线 var](#3.4.双前导和双后导下划线 var)
[3.5.单独下划线 _](#3.5.单独下划线 _)
1.基本语法
def 函数名(参数列表):
"""文档字符串(可选)"""
函数体
return 返回值 # 可选
2.函数命名规则
-
必须以字母或下划线开头
-
只能包含字母、数字、下划线
-
区分大小写
-
不能使用Python关键字
-
建议使用小写字母加下划线(snake_case)
合法函数名
def my_function(): pass
def _private(): pass
def calculate_sum(): pass非法函数名
def 123func(): pass # 数字开头
def def(): pass # 使用关键字
def my-func(): pass # 包含连字符
3.下划线的使用
3.1.单前导下划线 _var
class MyClass:
def __init__(self):
self.public_var = "公开变量"
self._protected_var = "受保护变量"
def _internal_method(self):
return "内部方法,不建议外部调用"
obj = MyClass()
print(obj.public_var) # 正常访问
print(obj._protected_var) # 可以访问,但不建议
obj._internal_method() # 可以调用,但不建议
约定俗成的"内部使用"标识,表示该变量或方法是"受保护的",仅供内部使用
注意:这只是约定,Python 并不会强制限制访问
3.2.单后导下划线 var_
# 错误:class 是关键字
# def make_class(class):
# 正确:添加后导下划线
def make_class(class_):
print(f"Creating class: {class_}")
make_class("MathClass")
# 其他常见场景
list_ = [1, 2, 3]
dict_ = {"a": 1, "b": 2}
避免与 Python 关键字冲突
3.3.双前导下划线 __var
class Parent:
def __init__(self):
self.__private_var = "私有变量"
self.normal_var = "普通变量"
def __private_method(self):
return "私有方法"
class Child(Parent):
def show_vars(self):
# 无法直接访问父类的 __private_var
# print(self.__private_var) # AttributeError
pass
obj = Parent()
# print(obj.__private_var) # AttributeError
print(obj._Parent__private_var) # 通过修饰后的名称访问
名称修饰,Python 解释器会修改属性名以避免子类意外覆盖
名称修饰规则 :
__var会被转换为_ClassName__var
名称修饰的核心作用是防止意外覆盖,而不是实现真正的私有性(虽然不能直接访问,但知道名字后依然可以)
3.4.双前导和双后导下划线 __var__
class MyClass:
def __init__(self, name):
self.name = name
def __str__(self):
return f"MyClass: {self.name}"
def __len__(self):
return len(self.name)
def __add__(self, other):
return MyClass(self.name + other.name)
obj1 = MyClass("Hello")
obj2 = MyClass("World")
print(obj1) # 调用 __str__
print(len(obj1)) # 调用 __len__
print(obj1 + obj2) # 调用 __add__
Python 的双下划线魔术方法(如 init、str)是 Python 语言预定义的协议接口,用户应该只实现已有的标准方法来实现特定功能(如迭代器、上下文管理器等),而不要随意创造新的 xxx 形式的方法名,以避免与未来 Python 版本冲突并保持代码的可读性
常见魔术方法:
- init: 初始化
- str: 字符串表示
- repr: 开发者友好的字符串表示
- call: 使实例可调用
- getitem: 索引访问
3.5.单独下划线 _
临时变量或无关紧要的值,常用于:
-
忽略不需要的值
忽略循环中的值
for _ in range(5):
print("Hello")解包时忽略某些值
a, _, b = (1, 2, 3)
print(a, b) # 1 3忽略多个值
first, *_, last = [1, 2, 3, 4, 5]
print(first, last) # 1 5 -
交互式解释器中表示上一次结果
5 + 3
8
_ # 上次计算结果
8
_ * 2
16
3.6.总结
| 模式 | 含义 | 示例 |
|---|---|---|
_var |
内部使用(约定) | _internal_var |
var_ |
避免关键字冲突 | class_ |
__var |
名称修饰(私有) | __private_var |
__var__ |
魔术方法 | __init__ |
_ |
临时变量/忽略值 | for _ in range(10) |
4.参数类型
4.1.位置参数
def greet(name, age):
print(f"{name} is {age} years old")
greet("Alice", 25) # 必须按顺序传递
4.2.默认参数
def greet(name, age=18):
print(f"{name} is {age} years old")
greet("Bob") # 使用默认age=18
greet("Charlie", 22) # 覆盖默认值
默认参数必须放在位置参数之后
4.3.关键字参数
def student(name, age, grade):
print(f"{name}, {age}, {grade}")
student(age=20, name="David", grade="A") # 顺序可调换
Python支持按照关键字传参
4.4.可变参数
-
*args 接收任意多个位置参数(可以接收 0 个参数)
def sum_all(*args):
return sum(args)print(sum_all(1, 2, 3, 4, 5)) # 输出: 15
print(sum_all(10, 20)) # 输出: 30
*args 可以接收任意类型的参数
def demonstrate(*args):
print(f"参数数量: {len(args)}")
print(f"参数类型: {[type(arg).__name__ for arg in args]}")
print(f"参数内容: {args}")
demonstrate(10, "text", [1,2], None, lambda x: x)
# 输出:
# 参数数量: 5
# 参数类型: ['int', 'str', 'list', 'NoneType', 'function']
# 参数内容: (10, 'text', [1, 2], None, <function <lambda> at 0x...>)
-
**kwargs- 接收任意多个关键字参数(可以接收 0 个参数)def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")print_info(name="Alice", age=25, city="New York")
输出:
name: Alice
age: 25
city: New York
4.5.参数组合顺序
def func(位置参数, *args, 默认参数, **kwargs):
pass
def example(a, b, *args, c=10, **kwargs):
print(f"a={a}, b={b}, args={args}, c={c}, kwargs={kwargs}")
example(1, 2, 3, 4, c=20, x=100, y=200)
# 输出: a=1, b=2, args=(3, 4), c=20, kwargs={'x': 100, 'y': 200}
5.返回值
5.1.单个返回值
def add(x, y):
return x + y
result = add(5, 3) # result = 8
5.2.多个返回值(返回元组)
def get_min_max(numbers):
return min(numbers), max(numbers)
minimum, maximum = get_min_max([1, 2, 3, 4, 5])
# minimum=1, maximum=5
5.3.无返回值
def say_hello(name):
print(f"Hello, {name}")
# 隐式返回 None
result = say_hello("Alice") # result = None
6.文档字符串
def calculate_area(radius):
"""
计算圆的面积
参数:
radius (float): 圆的半径
返回:
float: 圆的面积
示例:
>>> calculate_area(5)
78.53981633974483
"""
import math
return math.pi * radius ** 2
# 查看文档
help(calculate_area)
print(calculate_area.__doc__)
7.函数作用域
def scope_demo():
# 函数内的变量在函数内部任何位置都可访问
if True:
local_var = "如果在其他语言中,这是块级作用域"
print(local_var) # Python中仍然可以访问
# 但函数内的变量不能从外部访问
scope_demo()
# print(local_var) # NameError
8.global与nonlocal
counter = 0
def increment():
global counter # 声明使用全局变量
counter += 1
return counter
print(increment()) # 1
print(increment()) # 2
print(counter) # 2
def outer():
x = "outer"
def inner():
nonlocal x # 声明使用外层函数的变量
x = "inner"
print(f"inner中: {x}")
inner()
print(f"outer中: {x}")
outer()
# 输出:
# inner中: inner
# outer中: inner