likes
comments
collection
share

Python入门指南(三)

作者站长头像
站长
· 阅读数 11

Python入门指南(三)

Python入门指南(三)

欢迎来到Python入门指南的第三部分!在前两部分,我们已经学习了Python的基础语法、数据类型、流程控制、函数、面向对象编程、模块与包、文件操作等核心知识。现在,让我们继续深入探索Python的更多高级功能和应用,帮助你更加熟练地掌握这门强大的编程语言。

1.高阶函数和Lambda表达式

高阶函数

高阶函数是指能够接受其他函数作为参数,或者返回一个新函数作为结果的函数。Python作为一门函数式编程语言,支持很好的高阶函数特性。

# map()示例:将列表中每个元素平方
numbers = [1, 2, 3, 4, 5]
squared = map(lambda x: x**2, numbers)  # 使用 map() 函数对列表中的每个元素进行平方操作
print(list(squared))  # 输出 [1, 4, 9, 16, 25]

# filter()示例:过滤出列表中的偶数
evens = filter(lambda x: x % 2 == 0, numbers)  # 使用 filter() 函数过滤出列表中的偶数
print(list(evens))  # 输出 [2, 4]

这段代码演示了使用 map() 函数和 filter() 函数的示例:

  1. 使用 map() 函数将列表 numbers 中的每个元素进行平方操作,即对每个元素应用一个平方的 lambda 函数。然后将结果转换为列表并打印输出。
  2. 使用 filter() 函数从列表 numbers 中过滤出所有偶数,即只保留满足条件的元素。通过使用一个 lambda 函数判断元素是否为偶数,然后将结果转换为列表并打印输出。

高阶函数使得代码更加简洁、抽象,增强了程序的可读性和可维护性。Python内置的map()filter()reduce()等都是常用的高阶函数。

Lambda表达式

Lambda表达式是一种匿名函数的简写形式,常与高阶函数一起使用,用于定义简单的单行函数。


# 计算两数之和
add = lambda x, y: x + y  # 定义匿名函数,接收两个参数,返回它们的和
print(add(3, 5))  # 输出 8

# 排序示例
students = [  # 定义包含学生信息的列表
    {'name': 'John', 'age': 22, 'score': 88},
    {'name': 'Emma', 'age': 19, 'score': 92},
    {'name': 'Michael', 'age': 25, 'score': 75}
]

# 按score升序排序
sorted_students = sorted(students, key=lambda x: x['score'])  # 使用 lambda 函数作为排序关键字
print(sorted_students)  # 输出按照学生分数升序排序的列表

这段代码包含了两个示例:

  1. 使用 lambda 表达式定义了一个名为 add 的匿名函数,该函数接收两个参数 xy,返回它们的和。然后通过 add(3, 5) 调用该函数,打印出结果 8。
  2. 定义了一个包含学生信息的列表 students,其中每个元素是一个字典,包含学生的姓名、年龄和分数。通过调用 sorted 函数对 students 列表进行排序,使用 lambda 函数作为排序关键字,按照学生的分数升序排列。最后,打印排序后的列表 sorted_students

Lambda表达式使代码更加简洁紧凑,适合用于简单的场景,但对于复杂的函数,还是应该使用常规的def语句定义函数。

2.迭代器和生成器

迭代器

迭代器是一种可以遍历容器对象中所有元素的对象,通过__iter__()__next__()方法来实现迭代,可用于自定义迭代对象。

# 自定义可迭代对象
class CountIter:
    def __init__(self, start, stop):
        self.start = start  # 初始化起始值
        self.stop = stop    # 初始化终止值
        
    def __iter__(self):
        return self  # 返回迭代器自身,因为迭代器就是自己
    
    def __next__(self):
        if self.start >= self.stop:  # 如果当前值大于等于终止值
            raise StopIteration      # 抛出StopIteration异常,结束迭代
        cur = self.start             # 获取当前值
        self.start += 1              # 更新当前值为下一个值
        return cur                   # 返回当前值

# 使用自定义的迭代器进行迭代,并打印每个值
for i in CountIter(5, 10):
    print(i, end=' ')  # 输出:5 6 7 8 9

这段代码示例定义了一个名为 CountIter 的类,用于生成一个指定范围内的整数序列。其 __iter__ 方法返回迭代器自身,而 __next__ 方法在每次迭代中返回下一个整数,直到达到指定的终止值为止。最后,通过 for 循环迭代 CountIter(5, 10) 实例,打印出整数序列。

迭代器的优点是节省内存,只需一个接一个地生成值,而无需一次性把所有值加载到内存中。Python内置的许多对象都是可迭代的,如列表、字典、文件等。

生成器

生成器是一种特殊的迭代器,使用yield关键字来生成值,无需显式实现迭代器协议。

# 生成器函数: 斐波那契数列
def fib(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
        yield a  # 生成斐波那契数列中的每一项
        
for num in fib(10):
    print(num, end=' ')  # 输出斐波那契数列前10项

这段代码定义了一个生成器函数 fib(n),用于生成斐波那契数列中的前 n 项。每次调用 yield a 语句都会生成斐波那契数列中的下一个数,并在循环中逐个打印出来。

主要步骤包括:

  1. 定义了一个名为 fib 的生成器函数,接受一个参数 n,表示要生成斐波那契数列的项数。
  2. 在函数内部使用 for 循环和 yield 关键字来生成斐波那契数列中的每一项。
  3. for 循环外部,通过 for num in fib(10): 来遍历生成的斐波那契数列前 10 项,并将其打印输出。

生成器函数每次调用next()时,会执行到离它最近的一个yield语句,返回产生的值并记住当前位置。生成器特别适合用于处理大量数据或无限流序列的场景。

3.装饰器

装饰器是Python的一种语法糖,是一个高阶函数,它可以在不改变原函数代码的情况下,对其进行包装,从而扩展原函数的功能。


# 简单示例: 装饰器函数
def log(func):
    def wrapper(*args, **kwargs):
        # 打印调用信息
        print(f'Calling {func.__name__}')
        # 调用原始函数
        result = func(*args, **kwargs)
        # 打印函数返回结果
        print(f'Function {func.__name__} returned {result}')
        return result
    return wrapper
    
@log
def add(x, y):
    return x + y
    
print(add(3, 5))  # 输出调用信息,结果为8

# 带参数的装饰器示例
def log_args(prefix):
    def decorator(func):
        def wrapper(*args, **kwargs):
            # 打印带有前缀的参数信息
            print(f'{prefix} Arguments: {args}, {kwargs}')
            # 调用原始函数
            return func(*args, **kwargs)
        return wrapper
    return decorator
    
@log_args('Add')     
def add(x, y):
    return x + y
    
print(add(3, 5))  # 先打印参数信息,再打印8  

这段代码演示了两种不同类型的装饰器示例:

  1. 简单示例

    • log 装饰器函数接受一个函数作为参数,并返回一个新的函数 wrapper
    • wrapper 函数中,先打印函数的调用信息,然后调用原始函数,并打印函数返回结果。
    • 使用 @log 语法装饰了 add 函数,以便在调用 add 函数时执行装饰器逻辑。
  2. 带参数的装饰器示例

    • log_args 是一个接受参数的装饰器工厂函数,返回真正的装饰器函数 decorator
    • decorator 函数中定义了一个新的函数 wrapper,用于打印带有前缀的参数信息,并调用原始函数。
    • 使用 @log_args('Add') 语法装饰了 add 函数,以便在调用 add 函数时执行装饰器逻辑,并传入前缀参数 'Add'

装饰器在Python Web框架、插件系统、日志系统等场景中被广泛使用,能有效提高代码的可重用性。Python内置了一些装饰器函数,如@classmethod@staticmethod等。

4.并发和异步编程

多线程与多进程

Python通过线程和进程,支持并发编程模型。线程适合I/O密集型任务,进程适合CPU密集型任务。

# 多线程示例
import threading
import time

def worker():
    # 打印当前线程名称
    print(f'Worker thread: {threading.current_thread().name}')
    time.sleep(2)  # 模拟耗时操作
    print('Worker finished')
    
threads = []
for i in range(5):
    # 创建线程并添加到列表中
    t = threading.Thread(target=worker)
    threads.append(t)
    t.start()  # 启动线程
    
for t in threads:
    t.join()  # 等待所有线程执行完毕
print('All threads finished')

# 多进程示例    
import multiprocessing as mp

def worker(num):
    # 打印工作进程编号
    print(f'Worker {num}')
    return
    
if __name__ == '__main__':
    # 创建进程池,指定进程数量为5
    pool = mp.Pool(processes=5)
    # 使用 map 方法分配工作任务给进程池中的进程
    results = pool.map(worker, range(5))
    # 关闭进程池,防止新的任务提交
    pool.close()
    # 阻塞主进程,直到所有子进程执行完毕
    pool.join()
    print('All processes finished')

这段代码展示了多线程和多进程的示例:

  1. 多线程示例

    • worker 函数模拟了一个耗时的工作任务,其中包含了线程的名称打印和延时操作。
    • 通过循环创建了5个线程,并将它们添加到列表中。
    • 启动每个线程,并等待所有线程执行完毕。
  2. 多进程示例

    • worker 函数用于模拟工作进程的工作,每个进程打印了自己的编号。
    • 主程序中创建了一个进程池,指定进程数量为5。
    • 使用 map 方法将工作任务分配给进程池中的进程,并等待它们执行完毕。
    • 最后关闭进程池,以防止新的任务提交,并等待所有进程执行完毕。

使用线程和进程时需注意潜在的同步、死锁、竞争状态等问题。Python内置的threadingmultiprocessing模块提供了相应的同步原语解决这些并发编程中的经典问题。

异步编程

Python从3.4版本开始引入了asyncio模块,支持异步编程,特别适合处理I/O密集型任务。


import asyncio

async def hello():
    # 打印 'Hello'
    print('Hello')
    # 异步等待1秒
    await asyncio.sleep(1)
    # 继续执行,打印 'World'
    print('World')
    
async def main():
    # 调用异步函数 hello()
    await hello()

# 运行主协程
asyncio.run(main())

这段代码使用了 asyncio 模块来实现异步协程。

  • hello 函数是一个异步协程函数,它打印 'Hello',然后使用 asyncio.sleep(1) 进行了异步等待1秒,最后打印 'World'。
  • main 函数也是一个异步协程函数,它调用了 hello 函数。
  • 使用 asyncio.run(main()) 运行了主协程,使程序执行异步任务。

异步编程使用协程(Coroutine)的方式避免阻塞等待,提高程序的响应能力。除了asyncio,还有很多第三方异步编程库,如aiohttptornado等。

5.数据科学和机器学习

Python生态中有大量优秀的科学计算、数据分析、机器学习、深度学习等模块和框架。

NumPy 的安装和使用

安装 NumPy

pip install numpy

创建文件numpydemo.py


# NumPy基本操作
import numpy as np

# 创建一个NumPy数组
arr = np.array([1, 2, 3, 4, 5])

# 计算数组的均值和标准差
print(arr.mean()) # 输出:3.0
print(arr.std())  # 输出:1.4142135623730951

# Pandas读取CSV
import pandas as pd

# 从CSV文件中读取数据
data = pd.read_csv('data.csv')

# 打印前5行数据
print(data.head())

# 统计数据摘要
print(data.describe())

# 机器学习示例
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

# 加载鸢尾花数据集
X, y = load_iris(return_X_y=True)

# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y)

# 创建逻辑回归模型
model = LogisticRegression()

# 在训练集上训练模型
model.fit(X_train, y_train)

# 在测试集上评估模型准确率
print(f'Accuracy: {model.score(X_test, y_test)}')

以上代码中:

  • 使用NumPy计算了数组的均值和标准差。
  • 使用Pandas读取了名为'data.csv'的CSV文件,并打印了数据的前5行以及统计摘要。
  • 使用Scikit-learn加载了鸢尾花数据集,并将数据集拆分为训练集和测试集。
  • 创建了一个逻辑回归模型,并在训练集上训练了该模型。
  • 最后,在测试集上评估了模型的准确率。

常用的数据科学库包括NumPy、Pandas、Matplotlib、Scikit-Learn等,深度学习框架有TensorFlow、PyTorch、Keras等。学习这些库需要一定的理论基础,如矩阵运算、概率统计、优化算法等。

6.实践项目和扩展学习

恭喜你完成了Python入门系列的学习!现在你已经掌握了Python的核心语法和高级特性,接下来可以动手做一些实践项目,加深对Python的理解。

之前写的两篇都是给大家留下一个扩展的示例,这次给大家留个作业,完成以下的代码将你的成果留在评论区。

题目如下:
  • 制作一个简单的命令行工具,如文件批量重命名工具

7. 总结

通过本篇 Python 入门指南的学习,你已经了解了 Python 的更多高级特性和功能,包括高阶函数、Lambda 表达式、迭代器和生成器、装饰器、并发和异步编程、数据科学和机器学习等方面的知识。这些内容将帮助你更加深入地理解和应用 Python,为进一步的学习和实践打下坚实的基础。

在下一篇指南中,我们将继续探讨 Python 的一些实用技巧和高级主题,敬请期待!Python入门指南(四)