문제

파이썬에서 패스 별 행동을 모방하고 싶습니다. 다시 말해, 제가 작성한 기능이 사용자 제공 데이터를 수정하지 않도록하고 싶습니다.

가능한 한 가지 방법은 딥 카피를 사용하는 것입니다.

from copy import deepcopy
def f(data):
    data = deepcopy(data)
    #do stuff

더 효율적이거나 그 이상이 있습니까? 피티닉 이 목표를 달성하는 방법으로 전달되는 객체에 대해 가능한 한 적은 가정을 세우고 (예 : .Clone () 메소드)

편집하다

기술적으로 파이썬의 모든 것이 가치로 전달된다는 것을 알고 있습니다. 나는 관심이 있었다 에뮬레이션 행동, 즉 기능으로 전달 된 데이터를 엉망으로 만들지 않도록합니다. 가장 일반적인 방법은 문제의 물체를 자체 복제 메커니즘이나 심해로 복제하는 것입니다.

도움이 되었습니까?

해결책

이 작업을 수행하는 Pythonic 방법은 없습니다.

파이썬은 시설을 거의 제공하지 않습니다 시행 개인 또는 읽기 전용 데이터와 같은 것들. Pythonic 철학은 "우리는 모두 성인에 동의하고있다"는 것입니다.이 경우 "기능이 데이터를 변경해서는 안된다"는 것이 사양의 일부이지만 코드에서 시행되지는 않습니다.


데이터 사본을 만들려면 가장 가까운 솔루션입니다. 하지만 copy.deepcopy, 비효율적 인 것 외에도 경고도 있습니다 ~와 같은:

딥 카피는 모든 것을 복사 할 수 있기 때문에 복사 할 수 있습니다. 예를 들어 사본 간에도 공유 해야하는 관리 데이터 구조.

[...]

이 모듈은 모듈, 메소드, 스택 추적, 스택 프레임, 파일, 소켓, 창, 배열 또는 유사한 유형과 같은 유형을 복사하지 않습니다.

따라서 내장 된 파이썬 유형 또는 자신의 객체를 다루고 있다는 것을 알고 있다면 권장합니다 (여기서 __copy__ / __deepcopy__ 특별한 방법, 자신의 것을 정의 할 필요가 없습니다. clone() 방법).

다른 팁

데코레이터를 만들고 복제 행동을 할 수 있습니다.

>>> def passbyval(func):
def new(*args):
    cargs = [deepcopy(arg) for arg in args]
    return func(*cargs)
return new

>>> @passbyval
def myfunc(a):
    print a

>>> myfunc(20)
20

이것은 가장 강력한 방법이 아니며 키 가치 인수 또는 클래스 방법 (자기 인수 부족)을 처리하지는 않지만 그림을 얻습니다.

다음 진술은 동일합니다.

@somedecorator
def func1(): pass
# ... same as ...
def func2(): pass
func2 = somedecorator(func2)

데코레이터가 클로닝을 수행하는 기능을 취하여 데코레이터 사용자가 복제 전략을 결정할 수 있도록 할 수도 있습니다. 이 경우 데코레이터는 아마도 클래스로 가장 잘 구현 될 것입니다. __call__ 우선.

다음과 같이 참조로 작동하는 몇 가지 내장형 타이프 만 있습니다. list, 예를 들어.

따라서 저에게 나에게 Pythonic은 패스별로 수행하는 방법은 다음과 같습니다.이 예에서는 다음과 같습니다.

list1 = [0,1,2,3,4]
list2 = list1[:]

list1[:] List1의 새 인스턴스를 작성하고 새 변수에 할당 할 수 있습니다.

어쩌면 하나의 인수를받을 수있는 함수를 작성한 다음 유형을 확인한 결과, 결과적으로 통과 된 인수의 새로운 인스턴스를 반환 할 수있는 내장 작업을 수행 할 수 있습니다.

앞서 말했듯이, 그들의 행동은 참고 문헌과 같다는 몇 가지 내장 유형 만 있습니다.이 예에서는 목록이 있습니다.

어쨌든 ... 도움이되기를 바랍니다.

일반적으로 데이터를 외부 API로 전달할 때는 데이터를 불변의 객체로 전달하여 데이터의 무결성을 보장 할 수 있습니다. 예를 들어 데이터를 튜플로 묶습니다. 코드로 방지하려고 시도한 경우 수정할 수 없습니다.

나는 다른 것을 알 수 없습니다 피티닉 옵션. 그러나 개인적으로 나는 더 선호합니다 방법.

class TheData(object):
  def clone(self):  """return the cloned"""

def f(data):
  #do stuff

def caller():
  d = TheData()
  f(d.clone())

나는 이것을 할 수있는 정말 피스닉 방법이 없다고 확신하지만, 나는 pickle 모듈은 비즈니스를 값으로 취급하는 모든 것에 대한 사본을 제공합니다.

import pickle

def f(data):
    data = pickle.loads(pickle.dumps((data)))
    #do stuff

추가로 user695800 답변, [:] 연산자와 함께 가능한 목록에 대한 값을 통과하십시오.

def listCopy(l):
    l[1] = 5
    for i in l:
        print i

호출

In [12]: list1 = [1,2,3,4]

In [13]: listCopy(list1[:])
1
5
3
4

list1
Out[14]: [1, 2, 3, 4]
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top