【发布时间】:2021-01-06 16:33:36
【问题描述】:
hasattr() 是一种方法吗?它确实将对象实例作为参数,但不用作object.hasttr()。我会说这不是一种方法吗?
【问题讨论】:
-
hasattr()是一个函数。
标签: python oop semantics hasattr
hasattr() 是一种方法吗?它确实将对象实例作为参数,但不用作object.hasttr()。我会说这不是一种方法吗?
【问题讨论】:
hasattr() 是一个函数。
标签: python oop semantics hasattr
Python 中的一切都是对象,甚至函数和方法。所以hasattr() 接受对象这一事实并没有什么特别之处,str() 和 input() 和 sum() 也是如此。
方法是通过作为属性访问对象而被绑定到对象的函数;所以"foo bar".split 给了你绑定的str.split 方法:
>>> "foo bar".split
<built-in method split of str object at 0x7f84bef6a730>
这个恰好是“内置”的,因为它是作为 Python 运行时的一部分实现的,但它与用 Python 编写的类上的函数没有什么不同。
调用它会返回方法的结果应用于它所绑定的字符串:
>>> method = "foo bar".split
>>> method()
['foo', 'bar']
我也可以直接使用,unbound:
>>> str.split("spam ham")
['spam', 'ham']
hasattr() 未绑定。这是一个功能。即使您尝试过*,也无法像使用 Python 函数那样绑定它。
添加到类中的 Python 函数在您将它们作为类实例的属性访问时自动成为方法:
>>> class KnightsWhoSayNi:
... pass
...
>>> def speak(self): return "Ni!"
...
>>> speak
<function speak at 0x10fe65f28>
>>> knight = KnightsWhoSayNi()
>>> hasattr(knight, "speak") # using that function you mentioned!
False
>>> KnightsWhoSayNi.speak = speak # adding the function to the class
>>> knight.speak # now it exists! As a method...
<bound method speak of <__main__.KnightsWhoSayNi object at 0x10fe71080>>
>>> knight.speak()
'Ni!'
注意speak() 是如何被赋予一个名为self 的参数,但我不必将它传入。因为该方法绑定 到该类的特定实例,所以采用了自动照顾。传入的第一个参数是实例。名称甚至无关紧要,但self 是惯例,最好坚持下去。
作为练习,您可以自己尝试上述示例。然后尝试将hasattr 添加到班级。你会发现你可以t use it like a method, it won't become bound via knight.hasattr`,实例不会作为第一个参数传入,你仍然需要传入两个参数才能让它工作。
如果您想深入了解,可以在Python Descriptors HOW-TO 中了解绑定的工作原理。不要担心,如果这感觉太大了一步,那是相当先进的。
* 预先阻止未拾取:您可以使用functools.partial() 或functools.partialmethod() 来模拟绑定,但这并不完全相同。 p>
【讨论】: