相关疑难解决方法(0)

"是"运算符与整数意外行为

为什么以下在Python中出现意外行为?

>>> a = 256
>>> b = 256
>>> a is b
True           # This is an expected result
>>> a = 257
>>> b = 257
>>> a is b
False          # What happened here? Why is this False?
>>> 257 is 257
True           # Yet the literal numbers compare properly
Run Code Online (Sandbox Code Playgroud)

我使用的是Python 2.5.2.尝试一些不同版本的Python,似乎Python 2.3.3显示了99到100之间的上述行为.

基于以上所述,我可以假设Python在内部实现,使得"小"整数以不同于大整数的方式存储,is运算符可以区分.为什么泄漏抽象?当我不知道它们是否是数字时,比较两个任意对象以查看它们是否相同的更好的方法是什么?

python int identity operators python-internals

476
推荐指数
11
解决办法
6万
查看次数

Python如何区分作为类成员的回调函数?

请看一个简单的例子:

class A:
  def __init__(self, flag):
    self.flag = flag

  def func(self):
    print self.flag

a = A(1)
b = A(2)
callback_a = a.func
callback_b = b.func

callback_a()
callback_b()
Run Code Online (Sandbox Code Playgroud)

结果是:

1
2
Run Code Online (Sandbox Code Playgroud)

它按预期运行.但我有一个问题.在C中,回调函数作为指针传递.在Python中,它应该有类似的方法来执行此操作,因此调用者知道函数的地址.但在我的例子中,不仅传递了函数指针,而且传递了参数(self),因为同一类的相同方法打印出不同的结果.所以我的问题是:

  1. Python中的这种方法在内存中只有一个副本吗?我的意思是任何方法的代码只有一个副本,在我的例子中,该方法不会被克隆.我认为它应该只有一个副本,但在这里我仍然提出这个问题,以获得更多的输入.

  2. 我记得Python中的所有内容都是一个对象.所以在我的例子中,是否有两个具有不同参数但只有一个代码副本的函数实例?

python

27
推荐指数
2
解决办法
2万
查看次数

为什么方法没有引用相等?

我有一个错误,我在使用时依赖于彼此相等的方法is.事实证明并非如此:

>>> class What(object):
    def meth(self):
        pass

>>> What.meth is What.meth
False
>>> inst = What()
>>> inst.meth is inst.meth
False
Run Code Online (Sandbox Code Playgroud)

为什么会这样?它适用于常规功能:

>>> def func():
    pass

>>> func is func
True
Run Code Online (Sandbox Code Playgroud)

python methods identity equality reference

14
推荐指数
1
解决办法
821
查看次数

为什么与 `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
查看次数

Python无法将绑定方法与自身进行比较

我试图编写一个测试,检查保存类的绑定方法的变量是否与该方法的另一个引用相同.通常这不是问题,但在同一类的另一个方法中完成时似乎不起作用.这是一个最小的例子:

class TestClass:
    def sample_method(self):
        pass
    def test_method(self, method_reference):
        print(method_reference is self.sample_method)
Run Code Online (Sandbox Code Playgroud)

我真的使用的是assert代替print,但是既不是在这里也不是在那里,因为最终的结果是相同的.测试运行如下:

instance = TestClass()
instance.test_method(instance.sample_method)
Run Code Online (Sandbox Code Playgroud)

结果是False即使我期待它True.这个问题在Python 3.5和Python 2.7(在Anaconda下运行)中体现出来.

我知道绑定方法是通过执行类似操作获得的闭包TestClass.test_method.__get__(instance, type(instance)).不过,我希望这self.sample_method已经是这样一个封闭的引用,使self.sample_methodinstance.sample_method代表相同的参考.

令我困惑的部分原因是pytest我正在运行的真实测试的输出(处理公关matplotlib):

assert <bound method TestTransformFormatter.transform1 of <matplotlib.tests.test_ticker.TestTransformFormatter object at 0x7f0101077b70>> is <bound method TestTransformFormatter.transform1 of <matplotlib.tests.test_ticker.TestTransformFormatter object at 0x7f0101077b70>>
E        +  where <bound method TestTransformFormatter.transform1 of <matplotlib.tests.test_ticker.TestTransformFormatter object at 0x7f0101077b70>> = <matplotlib.ticker.TransformFormatter object at 0x7f0101077e10>.transform
E        +  and …
Run Code Online (Sandbox Code Playgroud)

python

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