의 종류가 추적 할 수없는 가망 만 깊은 같은파이썬은 ..
예리스트하는 딕셔너리 또는 튜플과 같은 객체의 특정 유형, 복사하는 것입니다 deepcopy : [[1, <SomeObj>], <OtherObj>]
나는 깊은 복사 할을 첫 번째 목록 (그리고 물론 .. 1). 그러나 SomeObj
또는 OtherObj
이 아닙니다. 그들은 refereces로 체재해야한다.
의 종류가 추적 할 수없는 가망 만 깊은 같은파이썬은 ..
예리스트하는 딕셔너리 또는 튜플과 같은 객체의 특정 유형, 복사하는 것입니다 deepcopy : [[1, <SomeObj>], <OtherObj>]
나는 깊은 복사 할을 첫 번째 목록 (그리고 물론 .. 1). 그러나 SomeObj
또는 OtherObj
이 아닙니다. 그들은 refereces로 체재해야한다.
내가 아는 한, 그렇게 할 수있는 유틸리티가 없습니다. 내장 된 copy
과 deepcopy
은 개체가 자신의 __copy__
및 __deepcopy__
메서드를 제공하여 기본 동작을 재정의 할 것을 요구합니다. 어떤 좋은 생각이 아니므로 항상 같은 종류의 사본을 원한다면 ...
그렇게하기위한 기능을 작성하는 것은 어렵지 않아야합니다. 여기리스트, 튜플 및 dicts 작동 예는 다음과 같습니다
def mycopy(obj):
if isinstance(obj, list):
return [mycopy(i) for i in obj]
if isinstance(obj, tuple):
return tuple(mycopy(i) for i in obj)
if isinstance(obj, dict):
return dict(mycopy(i) for i in obj.iteritems())
return obj
와 나는 단지 deepcopy됩니다 어떤 파이썬 도구의 인식 아니에요 그렇게 할 수인가요 기본 유형 및 기타 요소를 참조로 유지합니다.
나는 (20 라인 이하) 작은 재귀 함수를 작성할 수 있어야한다고 생각한다.
당신은 당신이 그것을 필요로하는 각 클래스에서 __deepcopy__
방법을 재정 의하여 아주 쉽게 copy.deepcopy
와 함께 할 수있는 서로 다른 복사 동작에 따라합니다. 상황은, 당신은 단지 그것을 다시 다음 런타임에 __deepcopy__
기능을 설정할 수 있습니다 : 제거하여 더 큰 것들에 대한
import copy
class OtherObject(object):
pass
l = [[1, 2, 3], [4, 5, 6], OtherObject()]
# first, save the old deepcopy if there is one
old_deepcopy = None
if hasattr(OtherObject, __deepcopy__):
old_deepcopy = OtherObject.__deepcopy__
# do a shallow copy instead of deepcopy
OtherObject.__deepcopy__ = lambda self, memo: self
l2 = copy.deepcopy(l)
# and now you can replace the original behavior
if old_deepcopy is not None:
OtherObject.__deepcopy__ = old_deepcopy
else:
del OtherObject.__deepcopy__
>>> l[0] is l2[0]
False
>>> l[1] is l2[1]
False
>>> l[2] is l2[2]
True
는이보다 효율적으로 할 것 튜플 지점과의'[''및]'은' ['와']'를 사용하고'.items()'를 dict 브랜치에서'.iteritems()'로 바꾼다. 이러한 변경은 Pythonic 스타일입니다. –
@ChrisMorgan 답변이 업데이트되었습니다. 팁 주셔서 감사합니다, 나는이 형태를 몰랐다. – mgibsonbr
만약 당신이 익숙하지 않다면, (a) 생성자 표현식 ('['과']'을 꺼낼 때 얻는 것, 그렇지 않으면리스트 이해력)과 (b) 반복자 dict.items()'는리스트를 생성하고,'dict.iteritems()'는 반복자를 생성하며, 자세한 것은'dict' 문서를 참조하십시오. –