”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 理解 Python 中的复杂概念:问自己的问题以及如何通过示例使用它们

理解 Python 中的复杂概念:问自己的问题以及如何通过示例使用它们

发布于2024-11-04
浏览:428

Comprendre les notions complexes en Python : questions à se poser et comment les utiliser avec des exemples

Python 是一种多功能且易于理解的语言,使其成为初学者的热门选择。然而,它还提供了乍一看似乎很复杂的高级功能。理解这些复杂的概念对于编写高效、可维护和高性能的 Python 代码至关重要。

在本文中,我们将探讨 Python 中一些更复杂的概念,例如生成器、装饰器、上下文管理器、lambda 表达式和元类。我们将讨论有关何时使用它们的问题,并提供代码示例来说明它们的使用。

1. 发电机

什么是发电机?
生成器是一个函数,允许您使用yield 关键字创建自定义迭代器。生成器不会返回单个值,而是在迭代时生成一系列值。

什么时候使用它?
当您处理大型数据序列并希望节省内存时。
当你需要惰性计算时,即你不想提前计算所有的值。
创建无限或潜在无限的数据流。
示例代码

def compteur_infini():
    n = 0
    while True:
        yield n
        n  = 1

# Utilisation
compteur = compteur_infini()
print(next(compteur))  # Sortie: 0
print(next(compteur))  # Sortie: 1
print(next(compteur))  # Sortie: 2

为什么有效?
每次调用 next(counter) 都会执行该函数,直到下一个yield 语句,返回值并挂起函数状态,直到下一次调用。

2. 装饰器

什么是装饰器?
装饰器是一种函数,允许您修改或丰富另一个函数或方法的行为,而无需更改其源代码。它将一个函数作为输入,向其添加功能,然后返回一个新函数。

什么时候使用它?
通过附加代码丰富功能(日志记录、访问控制、超时)。
当多个函数需要类似的行为时避免代码重复。
为了分离关注点,保持主代码干净。
示例代码

def journalisation(func):
    def wrapper(*args, **kwargs):
        print(f"Appel de {func.__name__} avec {args} {kwargs}")
        result = func(*args, **kwargs)
        print(f"{func.__name__} a retourné {result}")
        return result
    return wrapper

@journalisation
def addition(a, b):
    return a   b

# Utilisation
resultat = addition(5, 3)
# Sortie:
# Appel de addition avec (5, 3) {}
# addition a retourné 8

为什么有效?
日志装饰器包装了 add 函数,在执行之前和之后添加消息。

3. 上下文管理器

什么是上下文管理器?
上下文管理器是一种结构,允许您通过确保正确初始化和清理资源(文件、连接等)来管理资源。它使用 enterexit 方法,通常与 with 语句一起使用。

什么时候使用它?
管理需要清理的资源(关闭文件、释放连接)。
确保异常不会妨碍资源清理。
提高管理资源时代码的可读性。
示例代码

class GestionFichier:
    def __init__(self, nom_fichier, mode):
        self.nom_fichier = nom_fichier
        self.mode = mode
        self.fichier = None

    def __enter__(self):
        self.fichier = open(self.nom_fichier, self.mode)
        return self.fichier

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.fichier:
            self.fichier.close()

# Utilisation
with GestionFichier('test.txt', 'w') as f:
    f.write('Bonjour, monde!')

为什么有效?
上下文管理器确保文件自动关闭,即使在写入过程中发生异常。

4. Lambda 表达式

什么是 lambda 表达式?
lambda 表达式是使用 lambda 关键字定义的匿名函数。它可以接受多个参数,但只能包含一个表达式。

什么时候使用它?
创建快速且简单的函数,通常作为另一个函数的参数。
当一个完整的函数定义对于一个简单的任务来说过于冗长时。
用于数据结构中的简单计算。
示例代码

# Liste de nombres
nombres = [1, 2, 3, 4, 5]

# Utilisation de lambda pour doubler les nombres
doubles = list(map(lambda x: x * 2, nombres))
print(doubles)  # Sortie: [2, 4, 6, 8, 10]

为什么有效?
表达式 lambda lambda x:x*2 被传递给 map,后者将其应用于列表中的每个元素。

  1. 元类 什么是元类? 元类是定义类本身行为的类。在Python中,一切都是对象,包括类。元类允许您通过修改类的行为或添加属性来控制类的创建。

什么时候使用它?
修改类的创建,例如通过保存类或修改它们。
实现需要动态类修改的单例、ORM 或框架。
当类装饰器不足以达到所需的控制级别时。
示例代码

class EnregistrementClasses(type):
    registre = {}

    def __new__(cls, name, bases, attrs):
        new_class = super().__new__(cls, name, bases, attrs)
        cls.registre[name] = new_class
        return new_class

class MonObjet(metaclass=EnregistrementClasses):
    pass

class MonAutreObjet(MonObjet):
    pass

# Utilisation
print(EnregistrementClasses.registre)
# Sortie: {'MonObjet': , 'MonAutreObjet': }

为什么有效?
RegisterClasses 元类修改 new 方法以保存在注册表中创建的每个类。

结论

Python 中的复杂概念,例如生成器、装饰器、上下文管理器、lambda 表达式和元类,为经验丰富的开发人员提供了相当大的功能和灵活性。通过了解何时以及如何使用它们,您可以编写更高效、可读且可维护的代码。

当你遇到复杂的问题时,问自己以下问题:

我需要安全地管理资源吗? (上下文管理器)
我可以从惰性计算中受益吗? (发电机)
我可以在不修改函数的情况下丰富它的行为吗? (装饰者)
我是否需要简单的功能来进行一次性操作? (Lambda 表达式)
我应该控制类的创建吗? (元类)
通过回答这些问题,您可以确定这些复杂的概念是否适合您的情况。

7. 其他资源

图书:
Luciano Ramalho 的 Fluent Python。
《高效 Python》作者:Brett Slatkin。
官方文档:
发电机
装饰器
上下文管理器
Lambda 表达式
元类
教程:
理解 Python 中的生成器
Python 装饰器指南
使用上下文管理器
感谢您的阅读!欢迎分享您自己的经验或在评论中提出问题。

版本声明 本文转载于:https://dev.to/jmegnidro/comprendre-les-notions-complexes-en-python-questions-a-se-poser-et-comment-les-utiliser-avec-des-exemples-32l0?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 反射动态实现Go接口用于RPC方法探索
    反射动态实现Go接口用于RPC方法探索
    在GO 使用反射来实现定义RPC式方法的界面。例如,考虑一个接口,例如:键入myService接口{ 登录(用户名,密码字符串)(sessionId int,错误错误) helloworld(sessionid int)(hi String,错误错误) } 替代方案而不是依靠反射...
    编程 发布于2025-07-23
  • C++20 Consteval函数中模板参数能否依赖于函数参数?
    C++20 Consteval函数中模板参数能否依赖于函数参数?
    [ consteval函数和模板参数依赖于函数参数在C 17中,模板参数不能依赖一个函数参数,因为编译器仍然需要对非contexexpr futcoriations contim at contexpr function进行评估。 compile time。 C 20引入恒定函数,必须在编译时进行...
    编程 发布于2025-07-23
  • 为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    使用php dateTime修改月份:发现预期的行为在使用PHP的DateTime类时,添加或减去几个月可能并不总是会产生预期的结果。正如文档所警告的那样,“当心”这些操作的“不像看起来那样直观。 ; $ date->修改('1个月'); //前进1个月 echo $ date->...
    编程 发布于2025-07-23
  • 在Python中如何创建动态变量?
    在Python中如何创建动态变量?
    在Python 中,动态创建变量的功能可以是一种强大的工具,尤其是在使用复杂的数据结构或算法时,Dynamic Variable Creation的动态变量创建。 Python提供了几种创造性的方法来实现这一目标。利用dictionaries 一种有效的方法是利用字典。字典允许您动态创建密钥并分...
    编程 发布于2025-07-23
  • 为什么Microsoft Visual C ++无法正确实现两台模板的实例?
    为什么Microsoft Visual C ++无法正确实现两台模板的实例?
    The Mystery of "Broken" Two-Phase Template Instantiation in Microsoft Visual C Problem Statement:Users commonly express concerns that Micro...
    编程 发布于2025-07-23
  • 使用jQuery如何有效修改":after"伪元素的CSS属性?
    使用jQuery如何有效修改":after"伪元素的CSS属性?
    在jquery中了解伪元素的限制:访问“ selector 尝试修改“:”选择器的CSS属性时,您可能会遇到困难。 This is because pseudo-elements are not part of the DOM (Document Object Model) and are th...
    编程 发布于2025-07-23
  • 为什么在我的Linux服务器上安装Archive_Zip后,我找不到“ class \” class \'ziparchive \'错误?
    为什么在我的Linux服务器上安装Archive_Zip后,我找不到“ class \” class \'ziparchive \'错误?
    class'ziparchive'在Linux Server上安装Archive_zip时找不到错误 commant in lin ins in cland ins in lin.11 on a lin.1 in a lin.11错误:致命错误:在... cass中找不到类z...
    编程 发布于2025-07-23
  • 为什么HTML无法打印页码及解决方案
    为什么HTML无法打印页码及解决方案
    无法在html页面上打印页码? @page规则在@Media内部和外部都无济于事。 HTML:Customization:@page { margin: 10%; @top-center { font-family: sans-serif; font-weight: bo...
    编程 发布于2025-07-23
  • 同实例无需转储复制MySQL数据库方法
    同实例无需转储复制MySQL数据库方法
    在同一实例上复制一个MySQL数据库而无需转储在同一mySQL实例上复制数据库,而无需创建InterMediate sqql script。以下方法为传统的转储和IMPORT过程提供了更简单的替代方法。 直接管道数据 MySQL手动概述了一种允许将mysqldump直接输出到MySQL clie...
    编程 发布于2025-07-23
  • 如何使用组在MySQL中旋转数据?
    如何使用组在MySQL中旋转数据?
    在关系数据库中使用mySQL组使用mySQL组进行查询结果,在关系数据库中使用MySQL组,转移数据的数据是指重新排列的行和列的重排以增强数据可视化。在这里,我们面对一个共同的挑战:使用组的组将数据从基于行的基于列的转换为基于列。 Let's consider the following ...
    编程 发布于2025-07-23
  • 如何在鼠标单击时编程选择DIV中的所有文本?
    如何在鼠标单击时编程选择DIV中的所有文本?
    在鼠标上选择div文本单击带有文本内容,用户如何使用单个鼠标单击单击div中的整个文本?这允许用户轻松拖放所选的文本或直接复制它。 在单个鼠标上单击的div元素中选择文本,您可以使用以下Javascript函数: function selecttext(canduterid){ if(do...
    编程 发布于2025-07-23
  • 在JavaScript中如何并发运行异步操作并正确处理错误?
    在JavaScript中如何并发运行异步操作并正确处理错误?
    同意操作execution 在执行asynchronous操作时,相关的代码段落会遇到一个问题,当执行asynchronous操作:此实现在启动下一个操作之前依次等待每个操作的完成。要启用并发执行,需要进行修改的方法。 第一个解决方案试图通过获得每个操作的承诺来解决此问题,然后单独等待它们: co...
    编程 发布于2025-07-23
  • 为什么我在Silverlight Linq查询中获得“无法找到查询模式的实现”错误?
    为什么我在Silverlight Linq查询中获得“无法找到查询模式的实现”错误?
    查询模式实现缺失:解决“无法找到”错误在银光应用程序中,尝试使用LINQ建立错误的数据库连接的尝试,无法找到以查询模式的实现。”当省略LINQ名称空间或查询类型缺少IEnumerable 实现时,通常会发生此错误。 解决问题来验证该类型的质量是至关重要的。在此特定实例中,tblpersoon可能需...
    编程 发布于2025-07-23
  • PHP未来:适应与创新
    PHP未来:适应与创新
    PHP的未来将通过适应新技术趋势和引入创新特性来实现:1)适应云计算、容器化和微服务架构,支持Docker和Kubernetes;2)引入JIT编译器和枚举类型,提升性能和数据处理效率;3)持续优化性能和推广最佳实践。 引言在编程世界中,PHP一直是网页开发的中流砥柱。作为一个从1994年就开始发展...
    编程 发布于2025-07-23
  • Spark DataFrame添加常量列的妙招
    Spark DataFrame添加常量列的妙招
    在Spark Dataframe ,将常数列添加到Spark DataFrame,该列具有适用于所有行的任意值的Spark DataFrame,可以通过多种方式实现。使用文字值(SPARK 1.3)在尝试提供直接值时,用于此问题时,旨在为此目的的使用column方法可能会导致错误。 df.with...
    编程 发布于2025-07-23

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3