Python学习4 之 【函数】(函数的相关语法、下划线的使用、global与nonlocal关键字)

目录

1.基本语法

2.函数命名规则

3.下划线的使用

[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.单独下划线 _)

3.6.总结

4.参数类型

4.1.位置参数

4.2.默认参数

4.3.关键字参数

4.4.可变参数

4.5.参数组合顺序

5.返回值

5.1.单个返回值

5.2.多个返回值(返回元组)

5.3.无返回值

6.文档字符串

7.函数作用域

8.global与nonlocal


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 的双下划线魔术方法(如 initstr)是 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
相关推荐
liu****2 小时前
LangChain-AI应用开发框架(一)
c++·python·langchain·本地部署大模型
天才测试猿2 小时前
接口自动化测试详解
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·接口测试
承渊政道2 小时前
【优选算法】(实战剖析链表核心操作技巧)
开发语言·数据结构·c++·vscode·学习·算法·链表
li星野2 小时前
DeepSeek-V3介绍
学习
白小筠3 小时前
Pytorch之张量的基本操作
人工智能·pytorch·python
self_correction3 小时前
Python工具
网络·python·安全
Fevered 路小小呀!3 小时前
mediapipe新版本怎么玩--面部特征检测
人工智能·python·计算机视觉
geyasi3 小时前
【Flask】四、flask连接并操作数据库
数据库·python·flask
正经人_x3 小时前
学习日记36:TokenSeg
学习