一、闭包与装饰器

1、闭包

在一个函数,比如func1中的内部定义了另外一个函数func2 并且函数1(func1)的返回值是函数2(func2)的引用 这种情况,我们称之为闭包 简单来说就是外部函数返回内部函数的引用就叫做闭包

def func1():
    print("函数1运行")
    def func2():
        print("函数2运行")
    func2()
    return func2
f2 = func1()
print(f2)
f2()

示例:龟兔赛跑

import time
import random

# 定义跑道长度
track_length = 10


def runtime(func):
    def wrapper():
        start_time = time.time()  # 记录函数执行开始时间
        func()  # 执行被装饰的函数(乌龟/兔子跑步逻辑)
        end_time = time.time()  # 记录函数执行结束时间
        print(func.__name__, "运行时间是", end_time - start_time, "秒")

    return wrapper


@runtime  # 用装饰器包装乌龟函数
def tortoise():
    # 乌龟跑10米,每米休息1秒
    for i in range(1, track_length + 1):
        print(f"乌龟跑了{i}米")
        time.sleep(1)   # 每跑1米休息1秒


@runtime  # 用装饰器包装兔子函数
def rabbit():
    # 兔子跑10米,每5米随机休息1-10秒
    for i in range(1, track_length + 1):
        if i % 5 == 0:  # 第5、10米时休息
            time.sleep(random.randint(1, 10))
        print(f"兔子跑了{i}米")


# 执行赛跑
print("===== 乌龟开始赛跑 =====")
tortoise()
print("\n===== 兔子开始赛跑 =====")
rabbit()

2、yield关键字

yield 是 Python 中的一个关键字,用于定义生成器函数。生成器函数返回一个迭代器,允许按需生成值,而不是一次性计算并返回所有值。这种惰性求值的方式可以节省内存,特别适合处理大量数据或无限序列。

# yield 关键字

def func1():
    return "自信的生命最美丽"
    print("含泪播种的人必须能含笑收获")


# r1 = func1()
# print(r1)

def func2():
    print("勤于反省,才有不断进步的可能")
    # yield返回的是一个生产器对象
    yield "一个人,想要优秀,你必须要敢于挑战"
    print("有志者事竟成,苦心人天不负")
    yield "第二个yield"
    print("第二个yield后边的print")


r2 = func2()
print(r2)
# r2.__next__()
# r2.__next__()
# r2.__next__()

# 生成器对象可以使用for循环来进行迭代
# for i in r2:
#     print(i)

count = 1
for i in r2:
    # 这里打印的i是生成器对象yield后边的那个返回值
    print(i)
    count += 1
    print(f"for循环调用生成器的{count}打印")
    print("*"*20)

二、Python高阶函数

1、lambda匿名函数

是一种简洁的匿名函数,通常用于需要简单函数但不想正式定义的情况。Lambda 函数可以接受任意数量的参数,但只能有一个表达式。

语法格式如下:

lambda arguments: expression
# 冒号前面是函数的参数,冒号后面是函数的运算逻辑
 

示例:计算两数之和

add = lambda x, y: x + y
print(add(5, 3))  # 输出 8
 

2、map函数

是一种高阶函数,用于将一个函数应用于一个或多个可迭代对象(如列表、元组等)的每个元素,并返回一个迭代器。这种操作通常称为“映射”,因为它将输入数据通过特定函数转换后映射到输出数据。

语法格式如下:

map(function, iterable, ...)
 
# 前面是方法名

示例:列表中元素都加1

my_list = [1, 2, 3, 4, 5]
def add_one(e):
    return e + 1
r = map(add_one, my_list)
print(list(r))

# print(list(map(lambda e:e+1, my_list)))

3、reduce函数

是一种高阶函数,用于将可迭代对象(如列表、元组)中的元素通过指定的函数累积计算为一个单一的结果。它通常需要两个参 数:一个二元操作函数和一个可迭代对象。

语法格式如下:

from functools import reduce
result = reduce(function, iterable[, initializer])
 
  • function:接收两个参数的函数,用于计算累积值。
  • iterable:可迭代对象(如列表、字符串等)。
  • initializer(可选):初始值,若提供则作为第一次计算的第一个参数。

示例

from functools import reduce

a = [2, 4, 6, 8, 10]


def add(x, y):
    return x + y
result = reduce(add, a)
print(result)

print(reduce(lambda x, y: x + y, a))

4、filter过滤器函数

用于根据条件筛选数组元素

示例

letter = ['a', 'B', 'c', 'D', 'e', 'F']
upper_letter = filter(lambda x: x == x.upper(), letter)
print(list(upper_letter))

student_name = ['John', 'Doe', 'Jane']
print(list(filter(lambda x: x.startswith("J"), student_name)))

三、进程与线程编程

进程是操作系统分配资源的基本单位,拥有独立的地址空间和系统资源。线程是进程内的执行单元,共享进程的资源,但拥有独立的栈和程序计数器。

示例:多进程编程代码演示

import time          # 用于设置进程休眠
from multiprocessing import Process  # 核心:创建子进程的类
import os            # 用于获取进程ID(PID)

# 子进程要执行的函数
def target_function():
    time.sleep(2)     # 模拟子进程执行耗时操作(2秒)
    print(f"子进程的ID:{os.getpid()}")  # 打印当前子进程的PID

if __name__ == '__main__':  # 多进程必须的保护机制(Windows系统必加)
    print(__name__)         # 输出:__main__(主进程执行时的特殊标识)
    print(f"主进程ID:{os.getpid()}")  # 打印主进程的PID

    ps = []  # 存储所有子进程对象,方便后续管理
    # 创建10个子进程
    for i in range(10):
        p = Process(target=target_function)  # 创建进程对象,指定要执行的函数
        p.start()  # 启动子进程(此时子进程开始执行target_function)
        ps.append(p)  # 将进程对象加入列表

    # 让主进程等待所有子进程运行完成后再停止
    for p in ps:
        p.join()  # 主进程阻塞,直到该子进程执行完毕

四、面向对象编程基础

面向对象编程(OOP)是一种编程范式,核心思想是将数据与操作数据的方法封装为对象。Python中通过类(class)实现OOP,支持封装、继承和多态三大特性。

1、类的定义与实例化

class Dog:
    def __init__(self, name):  # 构造方法
        self.name = name       # 实例属性
    
    def bark(self):            # 实例方法
        print(f"{self.name} says woof!")

# 实例化对象
my_dog = Dog("Buddy")
my_dog.bark()  # 输出: Buddy says woof!

2、封装

封装隐藏对象内部细节,仅暴露必要接口。通过私有属性(前缀__)和公有方法实现。

class BankAccount:
    def __init__(self, balance):
        self.__balance = balance  # 私有属性
    
    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount
    
    def get_balance(self):        # 公有方法访问私有属性
        return self.__balance

account = BankAccount(1000)
account.deposit(500)
print(account.get_balance())  # 输出: 1500

3、继承

子类继承父类的属性和方法,并可扩展或重写。

class Animal:
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        raise NotImplementedError("子类需实现此方法")

class Cat(Animal):
    def speak(self):  # 方法重写
        print(f"{self.name} says meow")

my_cat = Cat("Whiskers")
my_cat.speak()  # 输出: Whiskers says meow

4、多态

同一方法在不同类中有不同实现。

def animal_sound(animal):
    animal.speak()

class Duck(Animal):
    def speak(self):
        print(f"{self.name} says quack")

duck = Duck("Donald")
animal_sound(duck)  # 输出: Donald says quack
animal_sound(my_cat)  # 输出: Whiskers says meow

5、类属性与静态方法

类属性为所有实例共享,静态方法无需实例化即可调用。

class MathUtils:
    PI = 3.14159  # 类属性
    
    @staticmethod
    def add(a, b):
        return a + b

print(MathUtils.PI)        # 输出: 3.14159
print(MathUtils.add(2, 3)) # 输出: 5

6、魔术方法

通过特殊方法(如__str____eq__)定制对象行为。

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __str__(self):
        return f"Point({self.x}, {self.y})"
    
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y

p1 = Point(1, 2)
p2 = Point(1, 2)
print(p1)       # 输出: Point(1, 2)
print(p1 == p2) # 输出: True

更多推荐