当您需要在Python中动态访问对象的属性时,您可以使用内置函数hasattr(object, attribute)
或getattr(object, attribute)
。
然而,这似乎是语法的奇怪顺序。它的可读性和直觉性较差,因为它会破坏英语的常规句子结构。
if hasattr(person, age):
如果有属性人员年龄
将对象作为对象的方法更具可读性:
if person.hasattr(age):
如果Person有属性年龄
有没有特殊原因不以这种方式实施?我可以想象有些情况下你不确定对象是否是一个合适的对象,而不仅仅是None
,但在那些不确定的情况下你肯定可以使用内置函数来提高安全性。< / p>
还有一些其他的缺点或考虑因素我没想到会让这些不值得吗?
答案 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在内部使用它,所以你甚至可以覆盖它(如果你知道,你正在做什么)。