热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python编程中的高级技巧与应用

在Python编程中,掌握高级技巧对于提升代码效率和可读性至关重要。本文重点探讨了生成器和迭代器的应用,这两种工具不仅能够优化内存使用,还能简化复杂数据处理流程。生成器通过按需生成数据,避免了大量数据加载对内存的占用,而迭代器则提供了一种优雅的方式来遍历集合对象。此外,文章还深入解析了这些高级特性的实际应用场景,帮助读者更好地理解和运用这些技术。

python的一些高级用法


生成器和迭代器

在讲生成器之前需要先了解一下一个高级的用法,也是我在面试过程中被问到的一个问题,当时没搞明白面试官要考察我什么,就没答出来,有点尴尬。
问题是:怎么用一行程序生成一个1-10数字的平方的一个列表。
答:用列表生成式,[x * x for x in range(1, 11)]。

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
>>>> next(g)
0
>>> next(g)
1
>>> next(g)
4
>>> next(g)
9
>>> next(g)
16
>>> next(g)
25
>>> next(g)
36
>>> next(g)
49
>>> next(g)
64
>>> next(g)
81
>>> next(g)
Traceback (most recent call last):File "", line 1, in <module>
StopIteration

当然&#xff0c;上面这种不断调用next(g)实在是太变态了&#xff0c;正确的方法是使用for循环&#xff0c;因为generator也是可迭代对象&#xff1a;

>>> g &#61; (x * x for x in range(10))
>>> for n in g:
... print(n)
...
0
1
4
9
16
25
36
49
64
81

迭代器&#xff1a;

凡是可作用于for循环的对象都是Iterable类型&#xff1b;

凡是可作用于next()函数的对象都是Iterator类型&#xff0c;它们表示一个惰性计算的序列&#xff1b;

继承和多态

下面这是父类的定义&#xff1a;

class Animal(object):def run(self):print(&#39;Animal is running...&#39;)

下面是子类继承&#xff1a;

class Dog(Animal):def run(self):print(&#39;Dog is running...&#39;)def eat(self):print(&#39;Eating meat...&#39;)

当子类和父类都存在相同的run()方法时&#xff0c;我们说&#xff0c;子类的run()覆盖了父类的run()&#xff0c;在代码运行的时候&#xff0c;总是会调用子类的run()。这样&#xff0c;我们就获得了继承的另一个好处&#xff1a;多态。

多态也就是子类既有父类的数据类型也有子类的数据类型&#xff0c;但是父类没有子类的数据类型。&#xff08;这里的数据类型就是类名&#xff09;

要理解多态的好处&#xff0c;我们还需要再编写一个函数&#xff0c;这个函数接受一个Animal类型的变量&#xff1a;

def run_twice(animal):animal.run()animal.run()

>>> run_twice(Dog())
Dog is running...
Dog is running...

>>> run_twice(Animal())
Animal is running...
Animal is running...

你会发现&#xff0c;新增一个Animal的子类&#xff0c;不必对run_twice()做任何修改&#xff0c;实际上&#xff0c;任何依赖Animal作为参数的函数或者方法都可以不加修改地正常运行&#xff0c;原因就在于多态。

多态的好处就是&#xff0c;当我们需要传入Dog、Cat、Tortoise……时&#xff0c;我们只需要接收Animal类型就可以了&#xff0c;因为Dog、Cat、Tortoise……都是Animal类型&#xff0c;然后&#xff0c;按照Animal类型进行操作即可。由于Animal类型有run()方法&#xff0c;因此&#xff0c;传入的任意类型&#xff0c;只要是Animal类或者子类&#xff0c;就会自动调用实际类型的run()方法&#xff0c;这就是多态的意思&#xff1a;

对于一个变量&#xff0c;我们只需要知道它是Animal类型&#xff0c;无需确切地知道它的子类型&#xff0c;就可以放心地调用run()方法&#xff0c;而具体调用的run()方法是作用在Animal、Dog、Cat还是Tortoise对象上&#xff0c;由运行时该对象的确切类型决定&#xff0c;这就是多态真正的威力&#xff1a;调用方只管调用&#xff0c;不管细节&#xff0c;而当我们新增一种Animal的子类时&#xff0c;只要确保run()方法编写正确&#xff0c;不用管原来的代码是如何调用的。这就是著名的“开闭”原则&#xff1a;

对扩展开放&#xff1a;允许新增Animal子类&#xff1b;

对修改封闭&#xff1a;不需要修改依赖Animal类型的run_twice()等函数。

装饰器

这种在代码运行期间动态增加功能的方式&#xff0c;称之为“装饰器”&#xff08;Decorator&#xff09;。
装饰器的作用就是为已经存在的对象添加额外的功能。

具体用到的时候我有了更深的理解再补充

注册器

这个一般出现在比较大型的项目中。
这个注册器不是用户账号注册的模块&#xff0c;而是项目中注册模块的一个模块。举个例子&#xff0c;一个深度学习项目可能支持多种模型&#xff1b;具体使用哪种模型可能是用户在配置文件中指定的。最简单的实现方式&#xff0c;就是维护一个模型名称->模型类的字典。但每当你增加一个模型时&#xff0c;这个字典就需要手动维护&#xff0c;比较繁琐。本文介绍一种注册器的模块&#xff0c;你需要维护的是需要注册的模块的代码路径&#xff08;相对简介些&#xff09;。

其实说的简单点就是注册器就是一个自动维护的字典&#xff0c;将你定义的模块添加到项目中。

class Register:def __init__(self, registry_name):self._dict &#61; {}self._name &#61; registry_namedef __setitem__(self, key, value):if not callable(value):raise Exception(f"Value of a Registry must be a callable!\nValue: {value}")if key is None:key &#61; value.__name__if key in self._dict:logging.warning("Key %s already in registry %s." % (key, self._name))self._dict[key] &#61; valuedef register(self, target):"""Decorator to register a function or class."""def add(key, value):self[key] &#61; valuereturn valueif callable(target):# &#64;reg.registerreturn add(None, target)# &#64;reg.register(&#39;alias&#39;)return lambda x: add(target, x)def __getitem__(self, key):return self._dict[key]def __contains__(self, key):return key in self._dictdef keys(self):"""key"""return self._dict.keys()

主要看一下register函数&#xff0c;其实就是一个add模块。


推荐阅读
  • 本文档汇总了Python编程的基础与高级面试题目,涵盖语言特性、数据结构、算法以及Web开发等多个方面,旨在帮助开发者全面掌握Python核心知识。 ... [详细]
  • 深入解析Spring启动过程
    本文详细介绍了Spring框架的启动流程,帮助开发者理解其内部机制。通过具体示例和代码片段,解释了Bean定义、工厂类、读取器以及条件评估等关键概念,使读者能够更全面地掌握Spring的初始化过程。 ... [详细]
  • 社交网络中的级联行为 ... [详细]
  • java文本编辑器,java文本编辑器设计思路
    java文本编辑器,java文本编辑器设计思路 ... [详细]
  • 深入浅出TensorFlow数据读写机制
    本文详细介绍TensorFlow中的数据读写操作,包括TFRecord文件的创建与读取,以及数据集(dataset)的相关概念和使用方法。 ... [详细]
  • 本文介绍了如何利用Python进行批量图片尺寸调整,包括放大和等比例缩放。文中提供了详细的代码示例,并解释了每个步骤的具体实现方法。 ... [详细]
  • 2018-2019学年第六周《Java数据结构与算法》学习总结
    本文总结了2018-2019学年第六周在《Java数据结构与算法》课程中的学习内容,重点介绍了非线性数据结构——树的相关知识及其应用。 ... [详细]
  • Java 实现二维极点算法
    本文介绍了一种使用 Java 编程语言实现的二维极点算法。该算法用于从一组二维坐标中筛选出极点,适用于需要处理几何图形和空间数据的应用场景。文章不仅详细解释了算法的工作原理,还提供了完整的代码示例。 ... [详细]
  • 历经三十年的开发,Mathematica 已成为技术计算领域的标杆,为全球的技术创新者、教育工作者、学生及其他用户提供了一个领先的计算平台。最新版本 Mathematica 12.3.1 增加了多项核心语言、数学计算、可视化和图形处理的新功能。 ... [详细]
  • 深入解析ESFramework中的AgileTcp组件
    本文详细介绍了ESFramework框架中AgileTcp组件的设计与实现。AgileTcp是ESFramework提供的ITcp接口的高效实现,旨在优化TCP通信的性能和结构清晰度。 ... [详细]
  • 由二叉树到贪心算法
    二叉树很重要树是数据结构中的重中之重,尤其以各类二叉树为学习的难点。单就面试而言,在 ... [详细]
  • Coursera ML 机器学习
    2019独角兽企业重金招聘Python工程师标准线性回归算法计算过程CostFunction梯度下降算法多变量回归![选择特征](https:static.oschina.n ... [详细]
  • 云函数与数据库API实现增删查改的对比
    本文将深入探讨使用云函数和数据库API实现数据操作(增删查改)的不同方法,通过详细的代码示例帮助读者更好地理解和掌握这些技术。文章不仅提供代码实现,还解释了每种方法的特点和适用场景。 ... [详细]
  • 本文详细介绍了 Java 中 org.geotools.data.shapefile.ShapefileDataStore 类的 getCurrentTypeName() 方法,并提供了多个代码示例,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 本文详细介绍了Java库XChart中的XYSeries类下的setLineColor()方法,并提供了多个实际应用场景的代码示例。 ... [详细]
author-avatar
一枝草一滴露的执着
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有