簡體   English   中英

如何針對自定義類型調試調用Python的copy.deepcopy()的問題?

[英]How can I debug a problem calling Python's copy.deepcopy() against a custom type?

在我的代碼中,我試圖使用copy.deepcopy來獲取類的實例副本。 問題是在某些情況下出現以下錯誤是錯誤的:

TypeError: 'object.__new__(NotImplementedType) is not safe, use NotImplementedType.__new__()'

經過大量挖掘后,我發現我能夠使用以下代碼重現錯誤:

import copy
copy.deepcopy(__builtins__) 

問題似乎是在某些時候它試圖復制NotImplementedType內置。 問題是為什么這樣做? 我沒有在課堂上覆蓋__deepcopy__而且它不會一直發生。 有沒有人有任何關於追蹤制作此類副本的請求來自哪里的提示?

我已經在copy模塊本身中放置了一些調試代碼以確保這就是正在發生的事情,但問題發生的地方到目前為止在遞歸堆棧中很難做出我所看到的大部分內容。

最后,我在copy源代碼中進行了一些挖掘,並提出了以下解決方案:

from copy import deepcopy, _deepcopy_dispatch
from types import ModuleType

class MyType(object):

    def __init__(self):
        self.module = __builtins__

    def copy(self):
        ''' Patch the deepcopy dispatcher to pass modules back unchanged '''
        _deepcopy_dispatch[ModuleType] = lambda x, m: x
        result = deepcopy(self)
        del _deepcopy_dispatch[ModuleType]
        return result

MyType().copy()

我意識到這使用私有API,但我找不到另一種實現同樣的方法。 我在網上進行了快速搜索 ,發現其他人使用了相同的API而沒有任何麻煩。 如果它將來發生變化,我會受到打擊。

我也知道這不是線程安全的(如果一個線程需要舊的行為,而我在另一個線程上做副本我會被搞砸)但是現在再次對我來說不是問題。

希望在某些時候幫助別人。

你可以覆蓋__deepcopy__方法:( python文檔

為了讓類定義自己的副本實現,它可以定義特殊方法__copy __()__deepcopy __() 前者被稱為實現淺拷貝操作; 沒有傳遞其他參數。 調用后者來實現深拷貝操作; 它傳遞了一個參數,即備忘錄字典。 如果__deepcopy __()實現需要創建組件的深層副本,它應該調用deepcopy()函數,並將組件作為第一個參數,將備注字典作為第二個參數。

否則,您可以將模塊保存在全局列表或其他內容中。

您可以覆蓋包含一個指向模塊,通過使用類的deepcopy的行為咸菜協議 ,這是由復制模塊支持,如規定在這里 特別是,您可以為該類定義__getstate____setstate__ 例如:

>>> class MyClass:
...     def __getstate__(self):
...         state = self.__dict__.copy()
...         del state['some_module']
...         return state
...     def __setstate__(self, state):
...         self.__dict__.update(state)
...         self.some_module = some_module

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM