当前位置: 首页 > news >正文

Python 高手编程系列三千四百三十九 :避免现有名称

使用上下文中已经存在的名称是不好的做法,因为它会导致阅读代码时 — 特别是调
试时 — 非常混乱,例如以下代码:

def bad_citizen():
… os = 1
… import pdb; pdb.set
trace()
… return os

bad
citizen()
(4)bad
citizen()
(Pdb) os
1
(Pdb) import os
(Pdb) c
<module ‘os’ from ‘/Library/Frameworks/Python.framework/Versions/2.5/lib/
python2.5/os.pyc’>
在这个例子中,os 名称被代码屏蔽。内置函数名称和来自标准库的模块名称都应该避免。
尽量使用原创的名称,即使是上下文的局部名称。对于关键字而言,后缀下划线是一
种避免冲突的方法:
def xapian_query(terms, or
=True):
“”“if or_ is true, terms are combined with the OR clause”“”

注意,class 通常被替换为 klass 或 cls:
def factory(klass, *args,kwargs):
return klass(args, **kwargs)
参数的最佳实践
函数和方法的签名是代码完整性的保证,它们驱动函数和方法的使用并构建其 API。除
了我们之前看到的命名规则之外,对参数也要特别小心。这可以通过 3 个简单的规则来实现。
• 通过迭代设计构建参数。
• 信任参数和测试。
• 小心使用魔法参数
args 和
kwargs。
通过迭代设计构建参数
如果每个函数都有一个固定的、定义明确的参数列表,那么代码的鲁棒性会更好。但
这在第一个版本中无法完成,所以参数必须通过迭代设计来构建。它们应该反映创建该元
素所针对的使用场景,并相应地逐渐发展。
例如,如果添加了一些参数,它们应该尽可能有默认值,以避免任何退化:
class Service: # 版本 1
def _query(self, query, type):
print(‘done’)
def execute(self, query):
self._query(query, ‘EXECUTE’)
Service().execute(‘my query’)
done
import logging
class Service(object): # 版本 2
def _query(self, query, type, logger):
logger(‘done’)
def execute(self, query, logger=logging.info):
self._query(query, ‘EXECUTE’, logger)
Service().execute(‘my query’) # 旧式调用
Service().execute(‘my query’, logging.warning)
WARNING:root:done
如果一个公共元素的参数必须被修改,那么将使用一个 deprecation 进程,本节稍后将
对此进行说明。
信任参数和测试
考虑到 Python 的动态类型特性,有些开发人员在函数和方法的顶部使用断言(assertion)
来确保参数具有正确的内容,代码如下:
def division(dividend, divisor):
assert isinstance(dividend, (int, float))
assert isinstance(divisor, (int, float))
return dividend / divisor
division(2, 4)
0.5
division(2, None)
Traceback (most recent call last):
File “”, line 1, in
File “”, line 3, in division
AssertionError
这通常是那些习惯于静态类型、并且感觉 Python 中缺少点什么的开发者的做法。
这种检查参数的方法是契约式设计(Design by Contract ,DbC,参见http://en.wikipedia.org/
wiki/Design_By_Contract)编程风格的一部分。在这种设计中,在代码实际运行之间会检查
先决条件。
这种方法有两个主要问题。
• DbC 的代码对应该如何使用它进行解释,导致其可读性降低。
• 这可能使代码速度变慢,因为每次调用都要进行断言。
后者可以通过解释器的"-O"选项来避免。在这种情况下,在创建字节码之前,所有断
言都将从代码中删除,这样检查也就会丢失。
在任何情况下,断言都必须小心进行,并且不应该用于使 Python 变成一种静态类型语
言。唯一的使用场景就是保护代码不被无意义地调用。
在大多数情况下,健康的测试驱动开发(TDD)风格可以提供鲁棒性很好的基础代码。
在这里,功能测试和单元测试验证了创建代码所针对的所有使用场景。
如果库中的代码被外部元素使用,那么进行断言可能是有用的,因为传入的数据可能
会导致程序结束甚至造成破坏。这在处理数据库或文件系统的代码中可能发生。
另一种方法是模糊测试(fuzz testing,参见 https://en.wikipedia.org/wiki/Fuzzing),它通
过向程序发送随机的数据块来检测其弱点。如果发现了新的缺陷,代码会被修复以解决这
一缺陷,并添加一次新的测试。
让我们来关注一个遵循 TDD 方法的代码库,它向正确的方向发展,每当出现新的缺陷
时都会对其进行调整,从而鲁棒性越来越好。当它以正确的方式完成时,测试中的断言列
表在某种程度上变得类似于先决条件列表。

http://www.cnnetsun.cn/news/2884089.html

相关文章:

  • ViCA架构:优化多模态大语言模型的视觉处理效率
  • 网络小白也能懂:用BFD单臂回声给老旧设备做“心跳检测”
  • 接口测试需要验证数据库么
  • 避开STO交货单的坑:BAPI_OUTB_DELIVERY_CREATE_STO与BAPI_OUTB_DELIVERY_CHANGE的库位处理差异详解
  • 突破大众点评反爬技术:完整数据采集解决方案实战
  • 告别焊球!用混合键合(Hybrid Bonding)搞定3D芯片堆叠,保姆级工艺解析
  • Microchip USB Hub配置实战:如何让你的集线器变身多协议快充站(支持BC1.2/CDP/DCP/SE1)
  • CSS linear-gradient的‘渐变框’到底有多大?搞懂background-size和盒模型的关系,告别背景图错位
  • NCM音频格式转换:Go语言实现的高效解密与批量处理解决方案
  • 1688运营学习如何高效?推荐五个商家都在用的圈子
  • 深入理解STM32的‘看门狗’:从HAL库源码看IWDG如何守护你的嵌入式系统
  • VITS+Whisper微调:低延迟TTS实战
  • 接口防护别再乱接!TVS和电阻一前一后,效果天差地别(附实测对比)
  • 3分钟掌握AI字幕黑科技:让外语视频秒变中文同步字幕
  • LCA算法三兄弟:从‘爬楼梯’到‘坐电梯’,图解倍增与Tarjan到底快在哪
  • 从RGV到OHT:一文看懂工厂空中物流小车的前世今生与技术演进
  • 从Wi-Fi到5G:匹配滤波器如何成为现代无线通信的‘隐形守护者’?
  • 别再死记硬背了!用Verilog HDL写几行代码,轻松吃透逻辑代数三大定理
  • 别再只盯着SNP了!用WGS重测序做群体遗传,这5个关键参数(Fst、Pi、Tajima‘s D)你得会看
  • 腾讯二面被问:如何设计 Skill 来降低 Token 消耗?我说“渐进式加载“。面试官:就这一个?还有呢?我当场卡壳了。
  • 京东面试官盯着我简历:“单步准确率 94%,听着挺唬人,那你这 Agent 连跑 20 步,还剩多少?“ 我心算了一下,当场沉默
  • Genesis Plus GX:高精度世嘉模拟器核心技术解析与开发实践
  • 别再死记硬背了!用一张图彻底搞懂MOS管的三个工作区(附LTspice仿真验证)
  • 从libcamsja.dll到NXOpen:一个NX二次开发老鸟的刀路编辑功能迁移与避坑实录(NX12前后版本对比)
  • Ubuntu 22.04 桌面个性化进阶:从 Dock 布局到 Gnome Shell 扩展生态的完整配置指南
  • 从KF_GINS到PPP/INS:一个GNSS/INS初学者的紧组合算法实践指南(附i2NAV开源代码解读)
  • Adapter Tuning实战:如何像搭乐高一样,为你的大模型添加可插拔的‘技能模块’?
  • KMS智能激活脚本:让Windows和Office告别激活烦恼的终极方案
  • C# WinForms CSV导入功能演示工程(含源码、PPT说明与VS2019可运行方案)
  • STM32F103 USB开发避坑指南:搞懂那512字节SRAM和BTABLE寄存器,数据不丢包