返回顶部
首页 > 资讯 > 后端开发 > Python >Python常见的反模式有哪些
  • 762
分享到

Python常见的反模式有哪些

2023-06-15 13:06:51 762人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

本篇内容介绍了“python常见的反模式有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.对Iterable对象使用map()和fil

本篇内容介绍了“python常见的反模式有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

1.对Iterable对象使用map()和filter()

内置的 map 和 filter 可以帮助我们通过函数编程的原理在 Python 中转换 iterable 对象。

这两个方法都接受一个函数和一个 iterable 作为参数,并返回相应的对象。

通过将该对象作为参数传递到 Python 中的内置列表构造函数,可以将其转换为列表。

我们经常使用 lambda 函数作为 map、filter 函数的参数:

my_list = [1, 2, 3, 4 ,5, 6, 7, 8, 9, 10]  # 将每个元素乘以2 print(list(map(lambda x: x * 2, my_list)))  # [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]  # 过滤掉偶数 print(list(filter(lambda x: x % 2 == 0, my_list)))  # [2, 4, 6, 8, 10]

上面的代码看起来相当累赘和不清楚。使用列表理解可以实现相同结果:

my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  # 与map相同 print([x * 2 for x in my_list]) # [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]  # 与filter相同 print([x for x in my_list if x % 2 == 0]) # [2, 4, 6, 8, 10]

不使用lambda函数后,列表理解变得更具可读性和简洁性。

2.输入较大时使用列表理解

列表理解有助于我们编写出清晰、简洁的代码。

但是,列表理解总是为 iterable 中的每个值创建一个列表。当输入量非常大时,就会导致内存占用过大的问题:我们的机器可能会崩溃。

生成器表达式结合了列表理解和生成器这两个方面的优点,为处理大型输入序列提供了更有效的方法。

要创建生成器表达式,只需将列表中的 [] 方括号替换为()方括号。

Python常见的反模式有哪些

生成器表达式并不是创建一个全新的列表,而是创建一个迭代器。

这会降低创建速度并优化内存分配。我们可以使用 next 函数或通过循环访问生成器表达式的每个后续元素。

my_list = [1, 2, 3, 4 ,5, 6, 7, 8, 9, 10]  my_gen_expr = (x * 2 for x in my_list)  print(next(my_gen_expr)) print(next(my_gen_expr)) # >> # 2 # 4  for x in my_gen_expr:   print(x) # >> # 6 # 8 # 10 # 12 # 14 # 16 # 18 # 20

注:生成器表达式是有状态的,因此在重用时要注意。如果要多次使用迭代器,则可能需要重新创建迭代器。

3.不使用range()的情况

range 函数对迭代整数很有用。

for i in range(10):     print(i)

当迭代类似列表的数据结构时,我们可以完全依赖for循环语法来访问每个项目。代码如下:

my_list = [2, 4, 6, 8, 10]  for item in my_list:     print(item)  # Output: # 2 # 4 # 6 # 8 # 10

但是,当想要访问索引和元素时,我们可以使用列表长度下的 range 方法,如下所示:

my_list = [2, 4, 6, 8, 10]  for i in range(len(my_list)):     print("index: ", i, "value: ", my_list[i])      # Output: # index: 0 value: 2 # index: 1 value: 4 # index: 2 value: 6 # index: 3 value: 8 # index: 4 value: 10

代码看起来不可读,因为我们必须在列表上调用 len,然后使用 range 方法包装输出。为了使代码更加具有 python  风格,我们必须提高代码的可读性。

更好的方法是对 list 对象调用 enumerate 函数。这将创建一个生成器,生成列表项的索引和值。

my_list = [2, 4, 6, 8, 10]  for i, v in enumerate(my_list):     print("index: ", i, "value: ", v)      # Output: # index: 0 value: 2 # index: 1 value: 4 # index: 2 value: 6 # index: 3 value: 8 # index: 4 value: 10

代码看起来是不是更加干净了?

4.字典中键丢失的问题

字典具有快速访问、分配、插入和删除的能力,是一种非常流行的数据结构。

但是新手开发人员访问字典中不存在的密钥时经常会遇到问题。

crypto_price = {   "Bitcoin": 64000,   "Ethereum": 2300,   "Dogecoin": 0.12 }  crypto_price["XRP"]
Python常见的反模式有哪些

处理该类问题的其中一种方法是检查字典中是否存在密钥,代码如下:

key = "XRP"  if key not in crypto_price:     crypto_price[key] = 1.2      print(crypto_price[key])

另一种方法是使用 try/except 块,如下所示:

key = "XRP"  try:     xrp = crypto_price[key] except raise KeyError:     xrp = 1.2      crypto_price[key] = xrp

上面的代码确实实现了我们的目标,但是我们可以通过使用字典方法 get 进一步改进。

通过使用 get 方法来获取相应键的值,而不是使用方括号 [] 来访问字典的键。

另外,如果键不存在,get 方法将返回 None,而不是抛出 KeyError。如果缺少键而不是无键,还可以将参数传递给 get  方法以获取默认值。

key = "XRP"  if crypto_price.get("XRP") is None:   crypto_price["XRP"] = 1.2
ada = crypto_price.get("ADA", 0)  # Prints 0 print(ada)

5.惰性关键字和位置参数设计

Python函数能够同时接受位置参数和关键字参数。

位置参数是不后跟等号(=)和默认值的名称。

关键字参数后面跟一个等号和一个给出其默认值的表达式。

得益于这种设计,python函数的创建和重用非常灵活。

但是,定义函数时,错误的设计选择可能会导致代码中难以修复的错误。

我们以计算复利的函数为例:

# 复利计算器年/月复利 def calculate_compound_interest(principal, rate, time_in_years,                                 compounded_monthly, to_string):   t = 1   if compounded_monthly:     t = 12   amt = principal * (1 + rate/(t * 100)) ** (time_in_years * t)   if to_string:     return f"${amt - principal:.2f}"    return amt - principal          calculate_compound_interest(100, 5, 2, False, False)   # 10.25

调用函数时出现的一个问题是,两个布尔参数(compounded_monthly 和结尾的  to_string)很容易相互混淆。这就会出现难以追踪的问题。

我们可以通过如下方式更改函数定义来提高可读性:

# 复利计算器年/月复利 def calculate_compound_interest(principal, rate, time_in_years,                                 compounded_monthly=False, to_string=False):

通过将两个布尔参数指定为关键字参数,函数调用方可以显式地指定要设置的布尔值,这些值将覆盖默认值。

calculate_compound_interest(100, 5, 2, compounded_monthly=True) # 10.49413355583269  calculate_compound_interest(100, 5, 2, to_string=True) # '$10.25'

但是,这仍然会出现问题,主要原因是关键字参数是可选的,因为没有任何强制调用方将这些作为关键字参数使用。

因此,我们仍然可以使用旧方法调用该函数:

calculate_compound_interest(100, 5, 2, False, False)

解决该问题的方法是仅在定义函数时强制布尔参数为关键字:

# 复利计算器年/月复利 def calculate_compound_interest(principal, rate, time_in_years, *, # Changed                                 compounded_monthly=False, to_string=False):

我们看到,*符号表示位置参数的结束和仅关键字参数的开始。

如果这样调用:

calculate_compound_interest(100, 5, 2, False, False)

将发生以下错误:

--------------------------------------------------------------------------- TypeError                                 Traceback (most recent call last) <ipython-input-32-faf75d2ad121> in <module> ----> 1 print(calculate_compound_interest(1000, 5, 2, False, False)) TypeError: calculate_compound_interest() takes 3 positional arguments but 5 were given

但是,关键字参数及其默认行为仍将保持不变,如下所示:

alculate_compound_interest(100, 5, 2, compounded_monthly=True) # 10.49413355583269  calculate_compound_interest(100, 5, 2, to_string=True) # '$10.25'

然而,仍然存在一个问题。

假设调用者决定对前三个必需参数(principal、rate、time in years)混合使用位置和关键字。

如果这三个参数的函数参数名称发生更改,我们将看到Python解释器。它会这样说:

# 复利计算器年/月复利 def calculate_compound_interest(p, r, t_in_y, *, # Changed                                 compounded_monthly=False, to_string=False):
calculate_compound_interest(principal=1000, rate=5, time_in_years=2)  calculate_compound_interest(1000, 5, time_in_years=2)

将发生以下错误:

--------------------------------------------------------------------------- TypeError                                 Traceback (most recent call last) <ipython-input-36-42e7ec842cd5> in <module> ----> 1 calculate_compound_interest(principal=1000, rate=5, time_in_years=2) TypeError: calculate_compound_interest() Got an unexpected keyWord argument 'principal' --------------------------------------------------------------------------- TypeError                                 Traceback (most recent call last) <ipython-input-37-1bc57c40980f> in <module> ----> 1 calculate_compound_interest(1000, 5, time_in_years=2) TypeError: calculate_compound_interest() got an unexpected keyword argument 'time_in_years'

因为我们没有考虑调用方显式地使用位置参数,所以代码中断。

python3.8中引入了一个解决方案,我们可以使用/参数重新定义函数,该参数指示仅位置参数的结束位置。代码如下:

# 复利计算器年/月复利 def calculate_compound_interest(p, r, t_in_y, /, *,  # 改变                                 compounded_monthly=False, to_string=False):

现在这样调用函数就会产生正确的结果:

calculate_compound_interest(100, 5, 2, compounded_monthly=True) # 10.49413355583269  calculate_compound_interest(100, 5, 2, to_string=True) # '$10.25'

但是,如果我们这样调用:

calculate_compound_interest(p=1000, r=5, t_in_y=2)

也会显示相应的错误:

---------------------------------------------------------------------------  TypeError                                 Traceback (most recent call last)  <ipython-input-21-883e876a7e8b> in <module>  ----> 1 calculate_compound_interest(p=1000, r=5, t_in_y=2)        2  TypeError: calculate_compound_interest() got some positional-only arguments passed as keyword arguments: 'p, r, t_in_y'

“Python常见的反模式有哪些”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: Python常见的反模式有哪些

本文链接: https://lsjlt.com/news/280506.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Python常见的反模式有哪些
    本篇内容介绍了“Python常见的反模式有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.对Iterable对象使用map()和fil...
    99+
    2023-06-15
  • python网站常见的反扒方式有哪些
    本文小编为大家详细介绍“python网站常见的反扒方式有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“python网站常见的反扒方式有哪些”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。网站反爬虫方式:&nb...
    99+
    2023-06-27
  • Python常见的模块有哪些
    本篇内容主要讲解“Python常见的模块有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python常见的模块有哪些”吧!python可以做什么?如果把开发按照层次划分的话,可以分成系统开发...
    99+
    2023-06-02
  • 有哪些常见的设计模式
    这篇文章主要讲解了“有哪些常见的设计模式”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“有哪些常见的设计模式”吧!一、建造者模式建造者模式(Builder P...
    99+
    2024-04-02
  • ZooKeeper部署常见的模式有哪些
    单节点模式:ZooKeeper运行在单个节点上,适用于开发、测试或小规模部署。 多节点模式:ZooKeeper运行在多个节点...
    99+
    2024-04-02
  • Python中实现单例模式的常见方式有哪些
    Python 中实现单例模式的几种常见方式元类(Metaclass):class SingletonType(type): """ 单例元类。用于将普通类转换为单例类。 "&q...
    99+
    2023-05-14
    Python
  • Java常见设计模式有哪些
    这篇文章主要介绍Java常见设计模式有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、设计模式总述:1、什么是设计模式:设计模式是一套经过反复使用的代码设计经验,目的是为了重用代码、让代码更容易被他人理解、保证...
    99+
    2023-06-29
  • 常见的反爬虫机制有哪些
    这篇文章主要讲解了“常见的反爬虫机制有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“常见的反爬虫机制有哪些”吧!对爬虫用户而言,网站的反爬行机制可以说是其头号敌人。反爬机制是一种防止爬虫...
    99+
    2023-06-20
  • Java单例模式的常见写法有哪些
    这篇文章主要介绍“Java单例模式的常见写法有哪些”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java单例模式的常见写法有哪些”文章能帮助大家解决问题。1.饿汉模式饿汉模式也叫预加载模式,它是在类...
    99+
    2023-06-30
  • Python常见的异常有哪些
    这篇文章主要介绍“Python常见的异常有哪些”,在日常操作中,相信很多人在Python常见的异常有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python常见的异常有哪些”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-16
  • golang反射常见用法有哪些
    golang反射常见用法有:1、获取对象的类型信息;2、获取和设置对象的属性值;3、动态调用对象的方法;4、是一种复杂的机制。本教程操作环境:windows10系统、golang1.20.1版本、DELL G3电脑。Golang是一种现代的...
    99+
    2023-07-14
  • Python中有哪些常见的加密方式
    Python中有哪些常见的加密方式,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。前言我们所说的加密方式,都是对二进制编码的格式进行加密的,对应到Python中,则是我们的B...
    99+
    2023-06-02
  • Python导入模块常见的问题有哪些
    1. 导入的模块不存在:如使用了错误的模块名或者没有安装对应的模块。2. 模块中的函数或者变量不存在:如使用了模块中不存在的函数或者...
    99+
    2023-10-12
    Python
  • Hive中的数据仓库设计模式有哪些常见模式
    在Hive中,常见的数据仓库设计模式包括以下几种: 星型模式(Star Schema):星型模式是数据仓库中最常见的模式之一,通...
    99+
    2024-04-02
  • 网站的导航设计有哪些常见模式
    顶部导航栏:通常位于网页的顶部,包含网站的主要链接和页面分类。 侧边导航栏:位于网页的一侧,包含网站的主要链接和页面分类。 ...
    99+
    2024-04-17
    建站
  • 负载均衡有哪些常见的部署模式
    负载均衡有以下常见的部署模式: 集中式负载均衡:在一个独立的设备上进行负载均衡,将请求分发到多个后端服务器上。 分布式负载均...
    99+
    2024-04-17
    负载均衡
  • php常见设计模式和用途有哪些
    PHP常见的设计模式有以下几种:1. 工厂模式(Factory Pattern):用于创建对象,隐藏对象创建的具体细节,客户端只需要...
    99+
    2023-09-29
    php
  • JavaScript中常见的反模式是什么
    本篇内容主要讲解“JavaScript中常见的反模式是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript中常见的反模式是什么”吧!硬编码硬编...
    99+
    2024-04-02
  • Python常见的数据加密方式有哪些
    这篇文章主要介绍了Python常见的数据加密方式有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Python常见的数据加密方式有哪些文章都会有所收获,下面我们一起来看看吧。前言:常见的加密算法基本分为这几类...
    99+
    2023-06-30
  • 用Golang实现分布式系统的常见模式有哪些?
    在构建分布式系统时,遵循常见模式至关重要:分布式一致性: raft 共识算法用于确保节点一致性。负载均衡: 哈希环可将请求均匀分配到服务器组。消息队列: apache kafka 用于可...
    99+
    2024-05-08
    分布式系统 常见模式 redis git apache golang
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作