本文由编程派根据 Hacker News 上曾经排名第一的文章 编译而来,作者 Hynek Schlawack 是一名德国软件工程师。

他建议, 除非是编写只兼容 Python 3 的代码而且清楚地了解 hasattr() 的用法,否则不要使用 hasattr() 。

在 Python 2 下,不建议编写这样的代码:

if hasattr(x, "y"):

print(x.y)

else:

print("no y!")

更好的做法是像如下两例所示:

try:

print(x.y)

except AttributeError:

print("no y!")

或者

y = getattr(x, "y", None)

if y is not None:

print(y)

else:

print("no y!")

如果处理的不是用户自行创建的类,更应该采用上述写法。

上面有一处用到了 getattr() ,这里将属性缺失视作属性的值为 None (常见的情况),如果想与此区分开来,可使用一个标记值(sentinel value)。 getattr 的速度不比 hasattr() 低,因为二者的查找过程完全相同,并且后者不会保存结果(至少在CPython实现下是如此)。

为什么不建议使用 hasattr()

在 Python 2 下使用 hasattr() ,和下面的代码几乎没有分别:

try:

print(x.y)

except:

print("no y!")

但是这样会隐藏掉特性(property):

>>> class C(object):

... @property

... def y(self):

... 0/0

...

>>> hasattr(C(), "y")

False

对于第三方库中类,我们无法确定某个属性(attribute)是否为特性(或者之后某次更新将其变成特性),因此上面那样使用 hasattr() 是非常危险的。

你或许不信,但是 Hacker News 上确实有程序员回复说经历过这个情况, hasattr() 隐藏了一个非常深的错误,让程序调式工作变得异常艰难。

另外一个原因是,对特性使用 hasttr() 会执行它们的 getter 函数,但这样和 hasattr() 这个函数的名称并不相符。

不过,在 Python 3 中, hasattr() 不存在这些问题:

>>> class C:

... @property

... def y(self):

... 0/0

...

>>> hasattr(C(), "y")

Traceback (most recent call last):

File "", line 1, in

File "", line 4, in y

ZeroDivisionError: division by zero

因此,在编写兼容 Python 2 和 3 的混合代码时,要特别注意这个函数。另外,你应该想不到 hasattr() 会引发 ZeroDivisionError 吧?

留心的读者可能会问,如果出现AttributeError呢??的确,如果真出现,我们没有办法区分到底是因为真的缺失该属性,还是特性存在问题。 文首提到的写法可以将可能的错误减少为只有一种,避免出现 Python 2 和 3 之间让人困惑的行为差异 。.

结语

当然,在你自己写的代码中仍然可以使用 hasattr() ,但是 如果后来修改了类,记得也要修改对应的 hasattr() ,确保不会出错 。不过虽然这样可以少写些代码,但是却增加了不必要的心理负担。

python 排名函数_一个危险的Python函数,不推荐使用相关推荐

  1. python排名分析_用Python分析了近几年胡润排行榜,我酸了……

    10 月 20 日,胡润研究院发布<2020 胡润百富榜>,也就是富富富豪排行榜 杭州的马云毫无悬念的再次摘下中国首富桂冠,深圳的马化腾位列第二 榜单被我翻烂了,还是没有找到我的名字,难道 ...

  2. python 时间序列预测_使用Python进行动手时间序列预测

    python 时间序列预测 Time series analysis is the endeavor of extracting meaningful summary and statistical ...

  3. python 概率分布模型_使用python的概率模型进行公司估值

    python 概率分布模型 Note from Towards Data Science's editors: While we allow independent authors to publis ...

  4. python getattr函数_[转]Python中的getattr()函数详解

    看了下函数本身的doc getattr(object, name[, default]) -> value Get a named attribute from an object; getat ...

  5. python一些常用函数_【python】常用的一些内置函数

    1.cmp cmp(A,B)函数,比较A,B的大小,如果A大于B,返回1,A小于B返回-1,A等于B返回0 print cmp(12,33) >>>-1 print cmp(&quo ...

  6. python四大高阶函数_详谈Python高阶函数与函数装饰器(推荐)

    一.上节回顾 Python2与Python3字符编码问题,不管你是初学者还是已经对Python的项目了如指掌了,都会犯一些编码上面的错误.我在这里简单归纳Python3和Python2各自的区别. 首 ...

  7. python deepcopy函数_用Python解数独[6]:递归获得最终答案

    目录 用Python解数独[0] 用Python解数独[1]:求每个单元格的行值域 用Python解数独[2]:求列值域和九宫格值域 用Python解数独[3]:求总值域 用Python解数独[4]: ...

  8. python 不执行函数_解决python调用自己文件函数/执行函数找不到包问题

    写python程序的时候很多人习惯创建一个utils.py文件,存放一些经常使用的函数,方便其他文件调用,同时也更好的管理一些通用函数,方便今后使用.或是两个文件之间的class或是函数调用情况. 就 ...

  9. python diff函数_使用Python创建你自己的diff工具

    为什么我需要自己的diff工具? 我经常使用git跟踪我的编码项目.文章.业务工作等等.git的一个美妙之处在于,你可以通过简单地使用其内置的diff功能来轻松地比较你的工作的不同状态.要使用这个功能 ...

最新文章

  1. 分享预告:「数据安全问题」+「 股权与期权」
  2. linux下动态链接问题(so文件的编写与调用)
  3. 图像降噪算法——稀疏表达:K-SVD算法
  4. php 二维数组根据键值合并二维数组_php数组根据某键值,把相同键值的合并最终生成一个新的二维数组...
  5. 你知道从浏览器发送请求给SpringBoot后端时,是如何准确找到哪个接口的?(下篇)学废了吗?
  6. 查找文件中每行第二个单词_日语单词中的长短音区别在哪里,日语长短音发音有什么规律...
  7. 如何有效开展小组教学_如何有效地开展小组合作学习——数学科主题教研活动...
  8. Typecho Theme Aria书写自己的篇章
  9. NB-IoT的DRX、eDRX、PSM三个模式怎么用?
  10. 被苹果“先捧后杀”的操作系统
  11. textarea光标处插入文字
  12. 【SpringBoot】整合MyBatis
  13. VUE 日历 生成钉钉考勤系统
  14. java 泰勒级数_使用rSymPy计算泰勒级数
  15. 获取百度首页的源代码
  16. iatf16949标准三大过程_IATF16949要求的过程、文件、记录汇总
  17. pku_oj: W11-01 最大素数问题 (C++)
  18. Go语言入门【7】指针
  19. ssh 获取服务器文件命令,ssh读取服务器文件内容
  20. 面向对象三大特性(多态)

热门文章

  1. 【转】心目中的编程高手
  2. JS的正则表达式[收藏]
  3. android 通知折叠点击,如何折叠Android通知?
  4. 3. 离散时间鞅(REN)
  5. 【UWB】ELM,Extreme Learning Machine 极限学习机
  6. 【Paper】2014_多智能体系统一致性问题研究_唐骥宇
  7. 【控制】《鲁棒控制-线性矩阵不等式处理方法》-俞立老师-第9章-时滞系统的分析和综合
  8. P9 线性系统状态空间分析-《Matlab/Simulink与控制系统仿真》程序指令总结
  9. 3.10 直观理解反向传播-深度学习-Stanford吴恩达教授
  10. excel 多项式拟合数据