为什么对象没有hasattr和getattr作为属性?

时间:2016-10-11 14:46:50

标签: python class

当您需要在Python中动态访问对象的属性时,您可以使用内置函数hasattr(object, attribute)getattr(object, attribute)

然而,这似乎是语法的奇怪顺序。它的可读性和直觉性较差,因为它会破坏英语的常规句子结构。

  

if hasattr(person, age):
  如果有属性人员年龄

将对象作为对象的方法更具可读性:

  

if person.hasattr(age):
  如果Person有属性年龄

有没有特殊原因不以这种方式实施?我可以想象有些情况下你不确定对象是否是一个合适的对象,而不仅仅是None,但在那些不确定的情况下你肯定可以使用内置函数来提高安全性。< / p>

还有一些其他的缺点或考虑因素我没想到会让这些不值得吗?

2 个答案:

答案 0 :(得分:3)

您会找到相当多的类似示例 - 例如len(obj)而不是obj.length()hash(obj)而不是obj.hash()isinstance(obj, cls)而非{{1 }}。您可能还注意到,添加拼写为obj.isinstance(cls)而不是obj1 + obj2,减法拼写为obj1.add(obj2)而不是obj1 - obj2等...重点是某些内置“函数”是被视为运算符而不是真正的函数,并受“__magic__”方法(obj1.sub(obj2)__len____hash__等支持。

截至“为什么”,您必须询问GvR,但历史原因设置在旁边,它至少避免了很多命名空间污染/名称冲突。如果__add__已经是“有点但没有明确保留”的名称,您如何命名“Line”或“Rectangle”类的长度?内省如何理解length并不意味着Rectangle.length()是一个相当大的序列式对象?

使用通用的“运算符”函数(请注意,正确的运算符也作为函数存在,参见Rectangle模块)+“__ magic__”方法使意图明确,并为“用户空间”语义留下正常的名称。< / p>

wrt /“英语的常规句子结构”,我不得不说我并不在乎 - 我学到的第一种编程语言是Apple的超级脚本(后来变成了苹果脚本),我很快发现它无用冗长。

  

我可以想象有些情况你不确定对象是否存在   甚至是一个合适的对象,而不仅仅是无

operator 是“正确的”对象。 Python中的所有内容(以及您可以绑定到名称的所有内容)都是“正确的”对象。

答案 1 :(得分:1)

它是语言设计的一部分。我想你会找到一些关于它背后更复杂思想的文档,但关键点就像

  • 您建议在所有对象上使用对象的函数作为内置函数。为什么这个函数应该特定于这个对象?
  • 语义:getattr函数适用于对象,而不是对象的一部分。
  • 命名空间:对象的功能由您定义,而不是由语言定义。内部函数的格式为__getattr__,您可以在对象上找到此函数;-)。 getattr在内部使用它,所以你甚至可以覆盖它(如果你知道,你正在做什么)。