我有一個嵌套函數,我使用作爲回調平等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'))
但後來我遇到問題後,當我需要再次引用該嵌套函數:
pyglet.window.remove_handler('on_key_press', get_stop_function('ENTER'))
這並不是因爲蟒蛇方式對待職能的工作:
my_stop_function = get_stop_function('ENTER')
my_stop_function is get_stop_function('ENTER') # False
my_stop_function == get_stop_function('ENTER') # False
感謝兩位similarquestions我明白髮生了什麼,但我不確定我的案例的解決方法。我正在查看pyglet source code,它看起來像pyglet使用平等來找到要刪除的處理程序。
所以我的最後一個問題是:如何覆蓋內部函數的__eq__
方法(或其他一些dunder),以使相同的嵌套函數相等?
(另一種解決方法是將存儲功能自己的參考,但就是複製pyglet的工作,會變得混亂與許多回調以及反正我很好奇這個問題!)
編輯:實際上在上面鏈接的問題中,解釋了方法具有價值平等,但沒有引用平等。使用嵌套函數,您甚至不會獲得值相等,這是我所需要的。
EDIT2:我可能會接受畢波多黎各的答案,但沒有人知道爲什麼下面不工作:
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') == get_stop_function('ENTER') # False
get_stop_function('ENTER').__eq__(get_stop_function('ENTER')) # True
是否「相同功能」的意思是相同的代碼(如,通過兩個'get_stop_function'創建),等於代碼,或以相同的字節碼串不同的代碼?相同或相等的封閉?等等...... – abarnert
你實際上可以_can_覆蓋內部函數的'__eq__'。在Python 3.x中,'function'是可變的。問題是它不會有任何好處。 Python 3.x指定'__eq__'查找允許忽略實例的方法並直接進入類,並且至少CPython 3.0-3.4和PyPy3 2.1(它們是唯一存在的3.x實現)就是這樣做的。 – abarnert
另外,對於你的編輯:我敢肯定,如果函數是相等的,並且綁定的對象是相等的,這意味着方法與嵌套函數有同樣的問題 - 函數仍然需要比較相等。只是通常你不會自己創建綁定方法,它們是由類的描述符創建的,在這種情況下,它們的函數將始終是相同的。 (我感覺我沒有很好地解釋......) – abarnert