相关疑难解决方法(0)

如何测试函数的平等性或身份?

我希望能够测试两个可调用对象是否相同.我更喜欢身份语义(使用"是"运算符),但我发现当涉及方法时,会发生不同的事情.

#(1) identity and equality with a method
class Foo(object):
    def bar(self):
        pass
foo = Foo()
b = foo.bar
b == foo.bar    #evaluates True. why?
b is foo.bar    #evaluates False. why?
Run Code Online (Sandbox Code Playgroud)

我用Python 2.7和3.3(CPython)重现了这一点,以确保它不是旧版本的实现细节.在其他情况下,身份测试按预期工作(翻译会议从上面继续):

#(2) with a non-method function
def fun(self):
    pass
f = fun
f == fun    #evaluates True
f is fun    #evaluates True

#(3) when fun is bound as a method 
Foo.met = fun
foo.met == fun    #evaluates False
foo.met is fun    #evaluates False

#(4) with a callable data …
Run Code Online (Sandbox Code Playgroud)

python

17
推荐指数
1
解决办法
794
查看次数

为什么方法与自身不相同?

关于is运算符Python文档说:

对象标识的运算符isis not测试:x is y当且仅当xy是同一个对象时才是真的.x is not y产生反向真值.

我们试试看:

>>> def m():
...   pass
... 
>>> m is m
True
Run Code Online (Sandbox Code Playgroud)

Python文档也说:

由于自动垃圾收集,空闲列表和描述符的动态特性,您可能会注意到is操作符的某些使用中看似异常的行为,例如涉及实例方法或常量之间的比较.查看他们的文档了解更多信息.

>>> class C:
...   def m():
...     pass
... 
>>> C.m is C.m
False
Run Code Online (Sandbox Code Playgroud)

我搜索了更多的解释,但我找不到任何解释.

为什么是C.m is C.m假的?

我使用的是Python 2.x. 如下面的答案中所述,在Python 3.x中C.m is C.m是真的.

python comparison identity

13
推荐指数
2
解决办法
329
查看次数

Python 2.7中的`id`函数,`is`运算符,对象标识和用户定义的方法

Python 2.7中的代码结果让我感到矛盾.该is运营商应该与对象的身份工作,所以是id.但是当我查看用户定义的方法时,他们的结果会有所不同.这是为什么?

py-mach >>class Hello(object):
...  def hello():
...    pass
...
py-mach >>Hello.hello is Hello.hello
False
py-mach >>id(Hello.hello) - id(Hello.hello)
0
Run Code Online (Sandbox Code Playgroud)

我从Python数据模型的描述中发现以下摘录有些用处.但它并没有真正使一切清楚.id如果每次重新构造用户定义的方法对象,为什么函数返回相同的整数?

获取类的属性(可能通过该类的实例),如果该属性是用户定义的函数对象,未绑定的用户定义的方法对象或类方法对象,则可以创建用户定义的方法对象.当属性是用户定义的方法对象时,仅当从中检索它的类与存储在原始方法对象中的类相同或派生类时,才会创建新的方法对象; 否则,原始方法对象按原样使用.

python identity equality python-2.7

12
推荐指数
2
解决办法
5344
查看次数

为什么"是"运算符说这些方法不一样?

考虑以下代码:

class Person(object):
   def sayHello(self):
       return 'Hello'

print(Person().sayHello is Person().sayHello)
Run Code Online (Sandbox Code Playgroud)

我希望它能显示出真实.为什么显示False?

python identity class object python-3.x

11
推荐指数
2
解决办法
864
查看次数

Python"is"语句:比较未绑定方法时的意外行为

在Python 2.7.9中,当我将未绑定方法分配给新属性并按is语句进行比较时,结果为False:

In [1]: class A(object):
   ...:     def a(self):
   ...:         pass
   ...:

In [2]: A._a = A.a

In [3]: print A.a, A._a
<unbound method A.a> <unbound method A.a>

In [4]: print id(A.a), id(A._a)
4499595904 4499595904

In [5]: A.a is A._a
Out[5]: False
Run Code Online (Sandbox Code Playgroud)

这是非常反直觉的,我找不到任何参考或文档来解释这种行为.更重要的是,当我在Python 3.4.2中测试相同的代码时,结果变成了True.我猜这是Python 2.7中的一个错误,但在Python 3中得到修复,任何人都可以帮我找到发生这种情况的真正原因吗?

python interpreter python-2.7 python-3.x

11
推荐指数
0
解决办法
63
查看次数

为什么与 `is` 比较方法总是返回 False?

为什么这个返回 False

>>> class A:
...     def a_method(self):
...         pass
...     def b(self):
...         print(self.a_method is self.a_method)
... 
>>> c = A()
>>> c.b()
False
>>> c.a_method is c.a_method
False
Run Code Online (Sandbox Code Playgroud)

什么时候可以使用is函数

>>> def a(): pass
... 
>>> a is a
True
Run Code Online (Sandbox Code Playgroud)

python

6
推荐指数
0
解决办法
128
查看次数

嵌套函数相等的解决方法

我有一个嵌套函数,我用它作为回调pyglet:

def get_stop_function(stop_key):
    def stop_on_key(symbol, _):
        if symbol == getattr(pyglet.window.key, stop_key):
            pyglet.app.exit()
    return stop_on_key

pyglet.window.set_handler('on_key_press', get_stop_function('ENTER'))
Run Code Online (Sandbox Code Playgroud)

但是当我需要再次引用嵌套函数时,我会遇到问题:

pyglet.window.remove_handler('on_key_press', get_stop_function('ENTER'))
Run Code Online (Sandbox Code Playgroud)

由于python处理函数的方式,这不起作用:

my_stop_function = get_stop_function('ENTER')
my_stop_function is get_stop_function('ENTER')  # False
my_stop_function == get_stop_function('ENTER')  # False
Run Code Online (Sandbox Code Playgroud)

感谢两个类似的 问题我理解发生了什么,但我不确定我的案例的解决方法是什么.我正在查看pyglet源代码,它看起来像pyglet使用相等来找到要删除的处理程序.

所以我的最后一个问题是:如何覆盖内部函数的__eq__方法(或其他一些dunder),以便相同的嵌套函数相等?

(另一种解决方法是自己存储对函数的引用,但这会复制pyglet的工作,会因许多回调而变得混乱,反正我对这个问题很好奇!)

编辑:实际上,在我上面链接的问题中,它解释了方法具有值相等但不具有引用相等性.使用嵌套函数,您甚至无法获得值相等,这就是我所需要的.

编辑2:我可能接受Bi Rico的回答,但有人知道为什么以下不起作用:

def get_stop_function(stop_key):
    def stop_on_key(symbol, _):
        if symbol == getattr(pyglet.window.key, stop_key):
            pyglet.app.exit()
    stop_on_key.__name__ = '__stop_on_' + stop_key + '__'
    stop_on_key.__eq__ = lambda x: x.__name__ == '__stop_on_' + stop_key + '__'
    return stop_on_key

get_stop_function('ENTER') …
Run Code Online (Sandbox Code Playgroud)

python nested pyglet python-3.x

5
推荐指数
1
解决办法
170
查看次数

classmethod在每次访问时返回一个新对象

访问classmethod一个类总是返回一个不同的对象。这与实例或静态方法不同。

class Foo(object):
    @classmethod
    def foo_classmethod(cls):
        pass

    def foo_instancemethod(self):
        pass

    @staticmethod
    def foo_staticmethod():
        pass
Run Code Online (Sandbox Code Playgroud)

当试图比较

In [37]: print(Foo.foo_instancemethod is Foo.foo_instancemethod)
True

In [38]: print(Foo.foo_staticmethod is Foo.foo_staticmethod)
True

In [39]: print(Foo.foo_classmethod is Foo.foo_classmethod)
False
Run Code Online (Sandbox Code Playgroud)

Python 2和3中的行为相同。这看起来像是bug吗?我在酸洗Python3中的类方法并对未酸洗的is对象进行检查时遇到了这个问题。

python pickle class-method python-2.7 python-3.7

5
推荐指数
0
解决办法
55
查看次数

测试 Python 变量和可调用变量之间相等性的正确方法是什么?

比较变量是否包含我想要的可调用对象的正确方法是什么?我应该使用is运算符还是==运算符?

在下面的交互式会话中,我定义了两个可调用对象,fg。我将一个分配给变量a,另一个分配给变量b

现在,当我想检查是否a相同时f,两者a == fa is f可以工作。

>>> def f():
...     pass
...
>>> def g():
...     pass
...
>>> a = f
>>> b = g
>>> a == f
True
>>> a is f
True
>>> a == g
False
>>> a is g
False
>>> b == f
False
>>> b is f
False
>>> b == …
Run Code Online (Sandbox Code Playgroud)

python python-3.x

2
推荐指数
1
解决办法
676
查看次数