考虑以下代码:
class Person(object):
def sayHello(self):
return 'Hello'
print(Person().sayHello is Person().sayHello)
我希望它显示为True。为什么它显示为假?
答案 0 :(得分:15)
方法绑定到运行时的实例。运行以下代码时:
print(Person().sayHello is Person().sayHello)
你创建两个实例,每次你有不同的内存地址。
>>> Person().sayHello
<bound method Person.sayHello of <__main__.Person object at 0x7fbe90640410>>
>>> Person().sayHello
<bound method Person.sayHello of <__main__.Person object at 0x7fbe90640490>>
注意:我们在Python中拥有的只是运行时;没有单独的编译时间。
答案 1 :(得分:5)
它们是同一类的两个不同实例。 sayHello
函数是绑定方法。
也就是说,如果你有一个类实例:
p = Person()
并在其上查找属性:
p.sayHello
然后Python首先查看实例的实际属性,如果它没有在那里找到属性,它会查看该类。 如果找到该名称的类方法,则将其转换为绑定到此实例的绑定方法。这就是导致对象实例作为第一个参数(self
)传递给sayHello
的魔力。
所以Person().sayHello is Person().sayHello
创建两个实例,根据在类上定义的相同方法创建两个不同的绑定方法,因此is
返回False
因为它们是不同的方法。
答案 2 :(得分:4)
我将假设你故意比较方法对象本身 - 而而不是你真的想要比较输出字符串而忘记在{{1}之后放置()
}}
尝试此实验:
sayHello
您会看到a = Person()
b = Person()
a.sayHello
b.sayHello
显示为
a.sayHello
...而<bound method Person.sayHello of <__main__.Person instance at 0x102cc8ef0>>
显示相似,但具有不同的父实例指针:
b.sayHello
<bound method Person.sayHello of <__main__.Person instance at 0x102d31908>>
的一个实例的绑定方法本身是来自不同Person
实例的同名绑定方法的不同的实例(方法) 。您可以使用Person
和id(a.sayHello)
来确认这一点,它会返回两个相应绑定方法的标识哈希值 - 它们会有所不同。由于您的代码id(b.sayHello)
动态创建了两个Person().sayHello is Person().sayHello
个实例,因此情况与我的命名实例示例Person
和a
相同
答案 3 :(得分:-1)
如果您拨打True
:
sayHello
print(Person().sayHello() is Person().sayHello())
在您的代码中,您实际上是在比较对象上的方法并检查它们是否具有相同的身份(他们不会这样做)。另请注意:
之间的区别"Hello" is "Hello"
和
"Hello" == "Hello"
首先,你要比较对象的身份(由于重复使用的字符串是相同的,多次调用id("Hello")
来查看)。在第二个中,您将比较字符串的内容以查看它们是否相等(即具有相同的字符)。现在,相同的字符串也具有相同的标识,但我不确定该假设是否适用于所有Python实现。
答案 4 :(得分:-1)
如果你想要一个返回True
的表达式,你可以试试这个:
print(Person.sayHello is Person.sayHello)
只是为了增加混乱,执行:
>>> say = Person.sayHello
>>> say()
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
say()
TypeError: sayHello() missing 1 required positional argument: 'self'
甚至:
>>> say(say)
'Hello'
>>> say(None)
'Hello'
>>>
这是因为:
>>> say
<function Person.sayHello at 0x02AF04B0>
say
是指Person.sayHello
这是一个函数,可以调用,但需要一个参数,但在这种特殊情况下,参数是无关紧要的。
现在,如果您不想继续提供无用的参数,您可以自动绑定一个参数:
>>> p=Person()
>>> p.sayHello()
'Hello'
答案 5 :(得分:-2)
是运算符意味着两个变量都指向同一个对象,而不是具有相同的值。请参阅Stack Overflow问题 Understanding Python's “is” operator 。