Python 【函数,命名空间,闭包,装饰器,迭代器与生成器】

一、Python 概述与环境

Python 是一种高级、解释型、面向对象的编程语言,具有简洁易读的语法。在 Python 编程中,我们首先要了解一些基础概念,如标识符、数据类型、变量、运算符和程序流程控制等。上一篇我们已经详细概述了高级数据类型先来回顾一下。

1. 数据类型相关示例

# 元组
tuple_example = (12,)
print(tuple_example)

# 列表
list_example = []
list_example.append(1)
print(list_example)

# 字典
dict_example = {'name': 'John', 'age': 25}
print(dict_example)

# 集合
set_example = {1, 2, 3}
print(set_example)

2. 字符串方法示例

str_example = "hello world"
print(str_example.upper())  # 转换为大写
print(str_example.replace("world", "python"))  # 替换字符串

 详细见文章Python高级数据类型:集合,列表,元组,字典及其重点-CSDN博客

二、函数

1. 函数的定义与调用

函数是将一系列固定的功能模块封装到一起,方便在需要时进行调用,避免代码重复,便于开发和维护。

def add(a, b):
    c = a + b
    return c

result = add(1, 3)
print(result)

2. 函数的返回

函数可以有返回值,也可以没有返回值。如果没有写return语句,默认返回None

def no_return():
    print("This function has no return value.")

result = no_return()
print(result)  # 输出 None

def single_return():
    return 10

print(single_return())

def multiple_return():
    return 1, 2, 3

a, b, c = multiple_return()
print(a, b, c)

3. 函数的参数

        函数执行传参时,传的是内存地址

3.1 形参
  • 位置参数:按照位置顺序传递的参数。
  • 默认值参数:在定义函数时给参数指定默认值。(Python在创建函数的时候发现有参数有默认值,会在内部创建一块区域来维护这个值,在特定情况下,如果默认值是可变数据类型,函数内部要修改默认值,将该地址中的默认值改变)
  • 混合参数:当位置参数和默认值参数混合使用的时候  ,一定需要注意顺序,先有位置参数,再有默认值参数,默认参数放到非位置参数的右边,
def userInfo(id, name, address, phone, gender="男"):
    print(f"用户ID编号{id},用户名:{name},家庭住址:{address},联系方式:{phone},性别:{gender}")

userInfo("001", "张三", "学校", "1399999999", "女")
3.2 实参
  • 位置参数:按照位置顺序传递的实参。
  • 关键字参数:通过参数名传递的实参。
  • 混合参数:当位置参数和关键字参数混合使用的时候  ,一定需要注意顺序,先有位置参数,再有关键字参数,
userInfo(id="002", name="李四", address="北京", phone="1888888888")
3.3 动态参数

当参数个数不确定时,可以使用动态参数*args**kwargs

**接收到的是字典类型

*接收到的是元组类型

def aaa(*key):
    sum = 0
    print(type(key))
    for i in key:
        sum += i
    print(sum)

b = aaa(1,2,3,4,5)
print(b)
#运行结果为
<class 'tuple'>
15
None
None是因为没有return

 当动态参数和位置参数混合使用的时候,需要注意一下位置   先有位置参数,再有动态参数
  位置参数  >  默认参数 > 动态参数

   动态参数放在最右边,**kwargs放在*args的右边

def aaa(**key):
    sum = 0
    print(type(key))
    for i in key.values():
        sum += i
    print(sum)

b = aaa(a = 1,b = 2,c = 3,d = 4)
print(b)
3.3.1 定义函数时的*args与**kwargs 
def func(*args, **kwargs):
    pass

func("牛逼", "666", n=1, mm=2)

函数定义时,使用特殊语法来处理这两类参数:

  • *args:收集所有未被显式定义的位置参数,存储为一个元组
  • **kwargs:收集所有未被显式定义的关键字参数,存储为一个字典
3.3.2 实参中传递*args与**kwargs

1.形参固定,实参用*与**

def func(a1,a2):
    print(a1)
    print(a2)


func(*[11,22])

#会将*[11,22]打散,11传给a1,22传给a2

#输出 11 22

func(**{"a1":11,"a2":12})

#按照键值对的方式进行关键字传参 ,若找不到key值对应的关键字则会报错

#输出 11 22

2.形参用*与**,实参也用*与**

def func(*args,**kwargs):
    print(aegs)
    print(kwargs)


func(*[11,12,13],**{"a":11,"b":12,"c":13})

#  输出:
#  (11, 12, 13)
#  {'a': 11, 'b': 12, 'c': 13}

三、命名空间与作用域

1. 命名空间

  • 内置命名空间:Python 解释器内部运行时的空间。
  • 全局命名空间:在 Python 文件中直接声明的变量、函数所在的空间位置。
  • 局部命名空间:在函数内部声明的变量、函数所在的空间位置。

2. 作用域

        Python中以函数为作用域,函数的作用域是一个局部作用域。

  • 全局作用域:包含内置命名空间和全局命名空间。
  • 局部作用域:函数内部。

3. globalnonlocal关键字

globals()  用来查看全局作用域中的名称
locals()   用来查看当前局部作用域中的名称


global     将外部的全局变量引入局部
nonlocal   将局部的属性引入内嵌的函数中

# global关键字
name = "王自立"
def fun01():
    global name
    name = "张艺凡"
    print(name)

fun01()
print(name)

# nonlocal关键字
def fun02():
    name = "王自立"
    def fun03():
        nonlocal name
        name = "张三"
        print(name)
    fun03()
    print(name)

fun02()

四、闭包

闭包指的是满足以下几个条件的函数:

  1. 必须有一个内嵌函数。
  2. 内嵌函数必须引用外部函数中的变量。
  3. 外部函数的返回值必须是内嵌函数。
def outer(fun):
    def inner():
        print("事务开始")
        fun()
        print("事务提交")
    return inner

五、装饰器模式

Python 装饰器允许在不修改原有函数代码的基础上,动态地增加或修改函数的功能,装饰器本质上是一个接收函数作为输入并返回一个新的包装过后的函数的对象。

 1.调用方式:

        方式一: 外层函数(待执行的函数名)()
            decorator(add)()
            decorator(delete)()
        
        方式二:在待执行的函数上标明装饰器注解  @装饰器函数名

def outer(fun):
    def inner():
        print("事务开始")
        fun()
        print("事务提交")
    return inner

@outer
def add():
    print("增加事务操作")

def dele():
    print("删除事务操作")

def upd():
    print("增更新事务操作")

outer(add)()
add()

2. 具体示例

def decorator_function(original_function):
    def wrapper(*args, **kwargs):
        # 这里是在调用原始函数前添加的新功能
        before_call_code()
       
        result = original_function(*args, **kwargs)
       
        # 这里是在调用原始函数后添加的新功能
        after_call_code()
       
        return result
    return wrapper

# 使用装饰器
@decorator_function
def target_function(arg1, arg2):
    pass  # 原始函数的实现

解析:decorator 是一个装饰器函数,它接受一个函数 func 作为参数,并返回一个内部函数 wrapper,在 wrapper 函数内部,你可以执行一些额外的操作,然后调用原始函数 func,并返回其结果。

  • decorator_function 是装饰器,它接收一个函数 original_function 作为参数。
  • wrapper 是内部函数,它是实际会被调用的新函数,它包裹了原始函数的调用,并在其前后增加了额外的行为。
  • 当我们使用 @decorator_function 前缀在 target_function 定义前,Python会自动将 target_function 作为参数传递给 decorator_function,然后将返回的 wrapper 函数替换掉原来的 target_function
  • 示例来源:https://www.runoob.com/python3/python-decorators.html

3.装饰有参数的函数

def f1(func):
    def add(a,b):
        return func(a,b) + 1   #add中的函数必须包含要接受的参数
return add

@f1
def greet(a,b):
    return a+b

print(greet(1,2))

4.装饰器带参数修饰函数

   因为装饰器也是一个函数,即装饰器本身也可以带参数,此时装饰器需要再多一层的内嵌函数。

def a1(*args):              #需要额外嵌套一层函数来接受传入的参数,使返回想要装饰的函数
    def a2(func):
        def a3(a,b):
            print("args:",args)
            result = func(a,b)
            return result + 1
        return a3
    return a2

@a1("带有参数的装饰器装饰带有参数的函数")
def greet(a,b):
    return a+b
print(greet(1,2))

   第一行先定义装饰器函数,由3个函数嵌套而成, 外层函数有一个装饰器自带的参数,内层函数不变,相当于闭包的嵌套。

六、迭代器与生成器

1. 迭代器

可以使用isinstance函数判断一个对象是否可迭代或是否是迭代器。

from collections.abc import Iterable, Iterator

list_example = [1, 2, 3]
print(isinstance(list_example, Iterable))  # 判断是否可迭代
print(isinstance(iter(list_example), Iterator))  # 判断是否是迭代器

2. 生成器

生成器本质上就是迭代器,函数中包含yield,那么这个函数称之为生成器函数。

# 通过生成器函数创建生成器
def fun01():
    print("今日20250402")
    yield "星期三"

    print("今日20250403")
    yield "星期四"

    print("今日20250404")
    yield "星期五"

    print("今日20250405")
    yield "星期六"

a = fun01()
print(a.__next__())
print(a.__next__())

# 通过生成器推导式创建生成器
list3 = (i for i in range(20) if i % 2 == 0)
for num in list3:
    print(num)

返回值:return ------> yield

1.调用  __next__()  找到生成器要执行的下一个元素
2.调用  send(值)  找到生成器要执行的下一个元素,还可以给上一个yield返回元素,第一个不能使用send
3.通过for循环
4.转换为list的列表

通过生成器推导式来创建生成器

list3 = (i for i in range(20) if i % 2 == 0)

小贴士:

列表推导式:[结果 for 变量 in 可迭代的对象 条件]
字典推导式:{结果 for 变量 in 可迭代的对象 条件}
集合推导式:{结果 for 变量 in 可迭代的对象 条件}
​生成器推导式:(结果 for 变量 in 可迭代的对象 条件)

七、匿名函数

匿名函数使用lambda关键字定义,适用于函数有返回值且函数体只有一行的情况。

add = lambda num1, num2: num1 + num2
print(add(1, 2))

八、内建函数

Python 提供了许多内建函数,如evalexecfilter等。

# eval函数
result = eval("1 + 2")
print(result)

# filter函数
numbers = [1, 2, 3, 4, 5]
even_numbers = filter(lambda x: x % 2 == 0, numbers)
print(list(even_numbers))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值