-1

hasattr()一种方法吗?它确实将对象实例作为参数,但不用作object.hasttr(). 我会说这不是一种方法吗?

4

1 回答 1

6

Python 中的一切都是对象,甚至是函数和方法。因此,接受一个对象的事实hasattr()并没有什么特别之处,str()andinput()和 也是如此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']

我也可以直接使用它,未绑定

>>> 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中了解绑定的工作原理。不要担心,如果这感觉太大了一步,那是相当先进的。


*抢先不选择:您可以使用or来模拟绑定,但这并不完全相同。functools.partial()functools.partialmethod()

于 2020-09-20T12:41:49.697 回答