python惰性

Lazy evaluation is a programming implementation paradigm that defers evaluating necessary operations until it’s requested to do so.

惰性评估是一种编程实现范例,用于延迟评估必要的操作,直到被要求这样做为止。

Usually, lazy evaluation is the preferred implementation when the operation is expensive, requiring either extensive processing time or memory. For example, in Python, one of the best-known techniques involving lazy evaluation is generators. Instead of creating whole sequences for the iteration, which can consume lots of memory, generators lazily evaluate the current need and yield one element at a time when requested.

通常,当操作昂贵,需要大量处理时间或内存时,首选惰性评估。 例如,在Python中,涉及延迟评估的最著名技术之一是生成器。 生成器懒惰地评估当前需求并在请求时一次生成一个元素,而不是为可能会消耗大量内存的迭代创建整个序列。

Besides the generators feature, outside the Python world, many other object-oriented programming languages, such as Swift and Kotlin, have lazy evaluations pertaining to objects. Specifically, you can specify that particular attributes of your custom instance objects are lazy in these languages, which means these attributes aren’t created until they’re explicitly accessed.

除了生成器功能外,在Python世界之外,许多其他面向对象的编程语言(如Swift和Kotlin)对对象的评估也比较懒惰。 具体来说,您可以指定自定义实例对象的特定属性在这些语言中是惰性的,这意味着这些属性只有在明确访问它们之后才能创建。

However, lazy attributes are less discussed in Python tutorials, as far as I know. Thus, to provide a proof of concept to Python learners, I’d like to introduce you to lazy attributes in Python.

但是,据我所知,懒惰属性在Python教程中很少讨论。 因此,为了向Python学习者提供概念证明,我想向您介绍Python中的惰性属性。

问题 (The Question)

Before we start discussing lazy attributes, some people may wonder why it matters or why we bother using lazy attributes.

在我们开始讨论惰性属性之前,有些人可能想知道为什么这很重要,或者为什么我们要麻烦使用惰性属性。

Here’s a possible scenario: Suppose we’re building a website that allows the user to interact with other users. One functionality is to view one’s followers, presented in a list. When we tap one user, we can view the user’s profile in a pop-up window. Let’s write some code to show a possible implementation.

这是一种可能的情况:假设我们正在建立一个允许用户与其他用户进行交互的网站。 一种功能是查看列表中显示的关注者。 当我们点击一​​个用户时,我们可以在弹出窗口中查看该用户的个人资料。 让我们写一些代码来展示可能的实现。

The problem
问题

As you can see, the current implementation involves fetching the profile data for all the users in the list. The operation of fetching the profile data can be expensive. It not only requires a trip to the remote server but also needs to store the data in the memory.

如您所见,当前的实现涉及为列表中的所有用户获取配置文件数据。 提取配置文件数据的操作可能很昂贵。 它不仅需要访问远程服务器,还需要将数据存储在内存中。

Importantly, these profile data aren’t required for displaying the needed user interface because the profile data are only used when a particular username is tapped. This use case sets the perfect foundation for us to implement lazy attributes.

重要的是,这些配置文件数据对于显示所需的用户界面不是必需的,因为仅当点击特定的用户名时才使用配置文件数据。 这个用例为我们实现惰性属性奠定了完美的基础。

解决方案1:使用“ @property” (Solution 1: Use ‘@property’)

To begin with, properties aren’t exactly the same concept as attributes in Python. Essentially, properties are decorated functions. And through the decoration, regular functions are converted into properties, which can be used as other attributes, such as supporting the dot-notation access.

首先,属性与Python中的属性并不完全相同。 本质上, 属性是装饰功能。 并通过修饰将常规函数转换为属性,这些属性可用作其他属性,例如支持点符号访问。

Thus, strictly speaking, creating a property isn’t really creating a lazy attribute itself. Instead, it’s just a matter of providing an interface to ease data handling. Behind the scenes, some other processes are involved. Let’s look at the following code before I explain how it works.

因此,严格来说,创建属性本身并不是在创建惰性属性。 取而代之的是,提供接口以简化数据处理即可。 在幕后,还涉及其他一些过程。 在解释其工作方式之前,让我们看一下下面的代码。

Lazy attribute: ‘@property’
惰性属性:“ @ property”

The above code has the following changes that are relevant to the implementation of the lazy attribute using the @property decorator.

上面的代码具有以下更改,这些更改与使用@property装饰器实现lazy属性有关。

  • We now have a protected attribute, _profile_data, which is created as None during the instantiation of the object, which is used as a placeholder for later data processing.

    现在,我们有了一个受保护的属性_profile_data ,该属性在对象实例化时被创建为None ,用作以后的数据处理的占位符。

  • We use the @property decorator to decorate the profile_data function, such that we can use the dot notation to access the attribute of profile_data.

    我们使用@property装饰器来装饰profile_data函数,以便可以使用点表示法来访问profile_data的属性。

  • In the profile_data function, we first check if the _profile_data attribute has data or not, and we only perform the heavy operation when it has no data (i.e., None). In our use case, if a particular user is never tapped for displaying their profile, we’ll never need to fetch the profile data, which is exactly what lazy evaluation is meant to be — it’ll only run the expensive operation only when it’s absolutely needed.

    profile_data函数中,我们首先检查_profile_data属性是否具有数据,并且仅当它没有数据时才执行重操作(即None )。 在我们的用例中,如果从不窃听特定用户的个人资料,我们将永远不需要获取个人资料数据,这正是惰性评估的含义–仅当它执行时,才运行昂贵的操作绝对需要。

Evaluate lazy attributes implemented with ‘@property’
评估使用'@property'实现的惰性属性

The above code was used to check if the implementation of lazy attributes worked as expected. We tried to access the attributes twice, and as you can see, the expensive operation ran only for the first time when the attribute was None. When we accessed the attribute for the second time, we got the fetched value immediately.

上面的代码用于检查惰性属性的实现是否按预期工作。 我们尝试过两次访问属性,如您所见,昂贵的操作仅在属性为None时才第一次运行。 当我们第二次访问该属性时,我们立即获得了获取的值。

解决方案2:使用“ __getattr__”特殊方法 (Solution 2: Use the ‘__getattr__’ Special Method)

In Python, functions that have double underscores before and after their names are called special or magic methods. Some people also call them dunder (i.e., double underscores) methods. One particular special method — __getattr__— can help us implement lazy attributes.

在Python中,名称前后带有双下划线的函数称为特殊方法或魔术方法。 有些人也称它们为dunder (即双下划线)方法。 一种特殊的特殊方法__getattr__可以帮助我们实现惰性属性。

With custom classes, instance objects have their attributes saved in a dictionary, which can be accessed using the special method __dict__. Specifically, this dictionary stores the attribute names as its keys and the corresponding attribute values as its values. Notably, if the dictionary doesn’t contain the specified attribute, the special method __getattr__ will get called as a fallback mechanism.

对于自定义类,实例对象的属性保存在字典中,可以使用特殊方法__dict__进行访问。 具体而言,该词典将属性名称存储为键,并将相应的属性值存储为值。 值得注意的是,如果字典不包含指定的属性,则特殊方法__getattr__将作为后备机制被调用。

It may sound confusing, but it’s not that hard with a real code example, as shown below.

听起来可能令人困惑,但是使用实际的代码示例并不难,如下所示。

Lazy attribute: ‘__getattr__’
惰性属性:“ __ getattr__”

The above code has the following changes that are relevant to the implementation of lazy attributes using the __getattr__ special method.

上面的代码具有以下更改,这些更改与使用__getattr__特殊方法实现惰性属性有关。

  • The updated __init__ method removes the attribute setting with the profile data. It’s a necessary change because if it’s set, even with a value of None, the attribute and its value will be stored in the object’s __dict__ attribute. In that case, the special method __getattr__ won’t get called.

    更新的__init__方法将删除配置文件数据的属性设置。 这是必要的更改,因为即使设置为None ,该属性及其值也将存储在对象的__dict__属性中。 在这种情况下,将不会调用特殊方法__getattr__

  • We also implement the __str__ method, which will be used to display the object for informational purposes (i.e., in the raised exception in the __getattr__ method).

    我们还实现了__str__方法,该方法将用于显示对象以供参考(即,在__getattr__方法中引发的异常中)。

  • In the __getattr__ method, we specified that when the profile_data attribute is accessed, we’ll fetch the data remotely and set the attribute using the setattr method.

    __getattr__方法中,我们指定访问profile_data属性时,将远程获取数据并使用setattr方法设置属性。

Testing of the lazy attribute
测试惰性属性

The above code was run to show whether the special method __getattr__ was able to help us implement lazy attributes.

运行上面的代码以显示特殊方法__getattr__是否能够帮助我们实现惰性属性。

When we tried to get the attribute named profile_data for the first time, the __getattr__ special method got called and created the attribute profile_data for us.

当我们第一次尝试获取名为profile_data的属性时, __getattr__特殊方法被调用并为我们创建了属性profile_data

Notably, the special __getattr__ method wasn’t called the second time, when we tried to retrieve the profile_data attribute, because this particular attribute has been available in the __dict__ dictionary. Let’s check that with the following code.

值得注意的是,当我们尝试检索profile_data属性时,没有再次调用特殊的__getattr__方法,因为该特殊属性在__dict__词典中可用。 让我们用以下代码检查一下。

‘__dict__’ and ‘__getattr__’
'__dict__'和'__getattr__'

As shown above, the profile_data attribute wasn’t in the dictionary. After we tried to retrieve it, the __getattr__ method got called, and the profile_data attribute and its value got saved in the dictionary.

如上所示, profile_data属性不在字典中。 在尝试检索它之后,调用了__getattr__方法,并将profile_data属性及其值保存在字典中。

The next time we accessed the attribute, it was directly returned from the dictionary without triggering the __getattr__ method. It’s exactly the behavior we wanted the lazy evaluation to have.

下次访问该属性时,该属性直接从字典中返回,而不会触发__getattr__方法。 这正是我们希望懒惰评估所具有的行为。

荣誉奖:'__getattribute__' (An Honorable Mention: ‘__getattribute__’)

Besides the __getattr__ method, there’s another special method called __getattribute__ in Python. Although they have similar names and work similarly to some extent, please don’t confuse these two different methods.

除了__getattr__方法之外, __getattr__还有另一个特殊的方法称为__getattribute__ 。 尽管它们具有相似的名称,并且在某种程度上相似地工作,但是请不要混淆这两种不同的方法。

Unlike the __getattr__ method, which doesn’t get called when a particular attribute is in the instance dictionary, the __getattribute__ method gets called every time an attribute is retrieved.

__getattr__方法不同,当实例字典中有特定属性时不会调用__getattr__方法,而每次检索属性时都会调用__getattribute__方法。

This feature is only useful when you expect the attribute to change very frequently and only the latest data are relevant. In these cases, we can achieve the effect by defining pertinent functions instead.

仅当您希望属性更改非常频繁且仅最新数据相关时,此功能才有用。 在这些情况下,我们可以通过定义相关函数来达到效果。

In other words, I don’t recommend you try implementing it because it’s tricky to make it function properly (see here for a brief discussion). For example, one particular problem you may run into is infinite recursive loops — the __getattribute__ method gets called an infinite number of times and will crash your program.

换句话说,我不建议您尝试实现它,因为要使其正常运行是很棘手的(请参见此处进行简要讨论)。 例如,您可能会遇到的一个特定问题是无限递归循环__getattribute__方法被调用了无数次,这将使您的程序崩溃。

结论 (Conclusions)

In this article, we were focused on discussing two practical ways (plus a tricky way not discussed in detail and not recommended) of implementing lazy attributes in Python: one using the @property decorator and the other using the __getattr__ special method.

在本文中,我们集中讨论了两种在Python中实现懒惰属性的实用方法(不建议详细讨论的一种棘手方法):一种使用@property装饰器,另一种使用__getattr__特殊方法。

Personally, I prefer using the property decorator, which is more straightforward and easier to understand. However, when you need to define multiple lazy attributes, the __getattr__ method is better because it provides a centralized place to manage these lazy attributes.

就我个人而言,我更喜欢使用属性装饰器,该装饰器更加简单明了。 但是,当您需要定义多个惰性属性时, __getattr__方法更好,因为它提供了一个集中的位置来管理这些惰性属性。

Thanks for reading.

谢谢阅读。

翻译自: https://medium.com/better-programming/how-to-create-lazy-attributes-to-improve-performance-in-python-b369fd72e1b6

python惰性


http://www.taodudu.cc/news/show-1873835.html

相关文章:

  • 如何识别媒体偏见_面部识别技术存在偏见:为什么我们不应该盲目相信新技术
  • 自然语言处理:简单解释
  • ai技术领先的企业_领先企业如何扩展AI
  • 机器学习为什么重要_什么是机器学习? 为什么对您的业务很重要?
  • 数据重塑_人工智能能否重塑全球力量平衡?
  • 平安科技一轮等多久_科技正等着我们成长
  • r语言 生成等差序列_使用序列模型生成自然语言
  • 人工智能火灾报警器_使用AI进行准确的火灾预测
  • ai/ml_您应该在本周(7月11日)阅读有趣的AI / ML文章
  • 西蒙决策_西蒙的象棋因子
  • ai的利与弊 辩论_为什么AI辩论失败了
  • k8s apollo_AI增强的Apollo 16素材让您以4K登上月球
  • ai疾病风险因素识别_克服AI的“蠕动因素”
  • 人工智能的未来是强化学习_多主体强化学习与AI的未来
  • ai人工智能的本质和未来_什么是人工智能,它将如何塑造我们的未来?
  • 日本初创公司Elix正在使用AI研究COVID-19药物
  • ai里怎样取消扩展外观_扩展AI:困难的5个原因
  • 自动化机器人 rpa_机器人过程自动化和机器人的出现
  • 月球 dem_通过“月球灾害”应对错误信息的流行
  • openai-gpt_GPT-3对非技术专业人员意味着什么
  • 自学人工智能途径_成为数据科学家,AI或ML工程师的自学途径
  • 为什么谋生是不道德的
  • 软件蓝图设计_智能企业的设计蓝图
  • 获得学士学位的机器学习工程工作
  • 无人驾驶 ai算法_质疑AI是否具有意图以及这对无人驾驶汽车意味着什么
  • openai-gpt_GPT-3:大惊小怪的是什么?
  • interpretable_Interpretable-AI:监督学习可能失败的地方
  • 生物物种数据库_一个半机械人的物种
  • pytorch使用模型预测_使用PyTorch从零开始对边界框进行预测
  • NLP对放射科医生的评价

python惰性_如何创建惰性属性以提高Python的性能相关推荐

  1. 在线python视频教程_【好程序员】2019 Python全套视频教程2

    2019千锋好程序员全新Python教程,深入浅出的讲解Python语言的基础语法,注重基本编程能力训练,深入解析面向对象思想,数据类型和变量.运算符.流程控制.函数.面向对象.模块和包.生成器和迭代 ...

  2. Python进阶丨如何创建你的第一个Python元类?

    摘要:通过本文,将深入讨论Python元类,其属性,如何以及何时在Python中使用元类. Python元类设置类的行为和规则.元类有助于修改类的实例,并且相当复杂,是Python编程的高级功能之一. ...

  3. 小白的第一本python书_学习《编程小白的第一本python入门书》

    ---恢复内容开始--- open打开一个txt文件,如果不存在则创建 1 file=open('/Users/Administrator/Desktop/file.txt','w')2 file.w ...

  4. python 分类_简单机器学习入门教程:用Python解决简单的水果分类问题

    在这篇机器学习入门教程中,我们将使用Python中最流行的机器学习工具scikit- learn,在Python中实现几种机器学习算法.使用简单的数据集来训练分类器区分不同类型的水果. 这篇文章的目的 ...

  5. 27岁学python编程_五一4天就背这些Python面试题了,Python面试题No12

    第1题: Python 中的 os 模块常见方法? os 属于 python内置模块,所以细节在官网有详细的说明,本道面试题考察的是基础能力了,所以把你知道的都告诉面试官吧 官网地址 https:// ...

  6. docker运行python程序_如何使用Docker运行多个Python脚本和一个可执行文件?

    我想创建一个包含两个Python包和一个包含一个可执行文件的包的容器.在 这是我的主包(dockerized_packeg)树:dockerized_project ├── docker-compos ...

  7. 微软 python教程_最强福利——来自微软的Python学习教程(开发指南)

    各位小伙伴们,大家有多久没有发现柳猫这么勤奋的更新啦~ 今天给小伙伴们带来微软的官方福利,你没看错,就是来自微软的官方Python学习教程(开发指南)~ 之前微软上线过一套 Python 教程< ...

  8. linux查看python环境_运维笔记linux环境提示python: command not found hello

    场景描述: 新部署的容器环境,终端执行python命令,提示没有该命令. 从报错异常可以看出,可能是python环境未安装. 分析思路: 检查python路径: 方式一:type -a python ...

  9. cmd中如何运行python文件_在cmd中运行.py文件: python的操作步骤

    在cmd中运行.py文件: python的操作步骤 1 打开cmd, 不改变运行的目录: 输入python 空格  调试好的python文件路径 或者python 空格  将python文件拖入cmd ...

  10. 初学者不建议月python吗_为什么我不建议你将python作为入门编程语言

    现在流行的编程语言里,python的热度可谓是热的通红,python以其短小精悍的语法.以其高效的开发,简单入门作为亮点,迅速的在各个领域占有一席之地. 然而,无论你说python有多好,我都不建议你 ...

最新文章

  1. 【问题收录】Ubuntu Starting LightDM Display Manager fail
  2. 用 Go 构建一个区块链 -- Part 5: 地址
  3. angular组件--tips提示功能
  4. View Components as Tag Helpers,离在线模板编辑又进一步
  5. 手机测评系列之vivox23
  6. 使用Tomcat配置域名
  7. ubuntu如何安装python36_在Ubuntu 16.04下安装Python3.6,ubuntu1604,Python36
  8. 你都用python来做什么-你都用Python来做什么?看看网友们的各种牛X操作
  9. pyspark--用法
  10. java中eq、ne、gt、lt、ge、le分别代表含义
  11. 大学生数学建模竞赛心得(提高篇) 转
  12. HDMI-FMC子卡的使用(基于VC707)(中)
  13. 年终囍一批、愁一批......浮躁啊,眼红啊,这个真有
  14. photoshop cs6基础学习
  15. SSRPanel 后端配置对接教程
  16. 《OpenDRIVE1.6规格文档》3
  17. 求整型矩阵主对角线元素之和
  18. CSS实现中英双语导航栏——利用块级元素隐藏实现
  19. 月二 周5 (前半写于周2)
  20. spring mvc Discus

热门文章

  1. 设计模式学习笔记之四:抽象工厂模式
  2. js 在线压缩混淆工具
  3. 20200115每日一句
  4. pdf文档有时打开乱码的解决方案
  5. 20191121每日一句
  6. 190421每日一句
  7. 3Dmax转的fbx模型导入unity赋材质不能改变颜色一直是黑色
  8. Atitit web httphandler的实现 java python node.js c# net php 目录 1.1. Java 过滤器 servelet 1 1.2. Python的
  9. Atitit nosql的概念与attilax的理解 目录 1. 常见的nosql 二、Redis,Memcache,MongoDb的特点 1 HBase 1 2. Nosql的核心nosql 1
  10. Atitit usrqbg1821 Tls 线程本地存储(ThreadLocal Storage 规范标准化草案解决方案ThreadStatic