hasattr是方法吗?

问题描述

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

解决方法

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']

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

>>> 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的参数的,但是我不必传递它。因为该方法 bound 绑定到特定的实例。类,它会自动处理。传入的第一个参数是实例。名称甚至都没有关系,但是self是惯例,最好遵循该惯例。

作为练习,您可以自己尝试上述示例。然后尝试将hasattr添加到类中。您会发现可以t use it like a method,it won't become bound via knight.hasattr`,实例不会作为第一个参数传递,您仍然必须传递两个参数才能使其完全起作用。

如果您想深入研究,可以在Python Descriptors HOW-TO中了解绑定的工作原理。


* 防止未拾取:您可以使用functools.partial()functools.partialmethod()模拟绑定,但这并不完全相同东西。