>

이 코드가 있습니다 :

# assignment behaviour for integer
a = b = 0
print a, b # prints 0 0
a = 4
print a, b # prints 4 0 - different!
# assignment behaviour for class object
class Klasa:
    def __init__(self, num):
        self.num = num
a = Klasa(2)
b = a
print a.num, b.num # prints 2 2
a.num = 3
print a.num, b.num # prints 3 3 - the same!

질문 :

<올>
  • 할당 연산자가 기본 유형과 다르게 작동하는 이유 클래스 객체 (기본 유형의 경우 값으로 복사, 클래스 객체의 경우 참조로 복사)?
  • 값으로 만 클래스 객체를 복사하는 방법?
  • C ++과 같은 기본 유형에 대한 참조를 만드는 방법int&b = a?
    • 답변 # 1

      이것은 많은 파이썬 사용자들에게 걸림돌입니다. 객체 참조 시맨틱은 C 프로그래머가 사용하는 것과 다릅니다.

      첫 번째 사례를 보자. 말할 때 a = b = 0 , 새로운 int  값 0 로 오브젝트가 작성됩니다.  그것에 대한 두 개의 참조가 작성됩니다 (하나는 a 입니다)  다른 하나는 b 입니다 ). 이 두 변수는 동일한 객체 (우리가 만든 정수)를 가리 킵니다. 이제 우리는 a = 4 를 실행합니다. . 새로운 int  가치 4 의 개체  만들어지고 a  그것을 가리 키도록 만들어졌습니다. 이는 4 에 대한 참조 수가   0 에 대한 하나의 참조 수  하나 줄였습니다.

      이것을 pyzwyz와 비교  C에서 a = 4 하는 메모리 영역  "점"을 쓴다. 와이즈 비즈  C에서 a 의미   a = b = 4 에 대한 두 개의 메모리에 기록됩니다.  그리고 다른 4 .

      이제 두 번째 경우 인 a   b 유형의 객체를 만듭니다. 참조 카운트를 1 씩 증가시키고 a = Klass(2) 를 만듭니다.  그것을 가리킨다. 와이즈 비즈단순히 무엇 Klass 걸립니다   a 를 가리킨다  같은 것을 가리키고 물건의 참조 카운트를 하나씩 증가시킵니다. 당신이 b = a 를 한 경우에 일어날 것과 같은 . a 를 인쇄하려고  그리고 b  동일한 객체를 역 참조하고 속성 값을 인쇄하기 때문에 동일합니다. 당신은 a = b = Klass(2) 를 사용할 수 있습니다  객체가 동일한 지 확인하는 내장 함수 ( a.num  그리고 b.num  동일한 식별자를 반환합니다). 이제 속성 중 하나에 값을 할당하여 객체를 변경합니다. id 부터  그리고 id(a)  동일한 객체를 가리키면 id(b) 를 통해 객체에 액세스 할 때 값의 변화가 보일 것으로 예상됩니다  또는 a . 그것이 바로 그 방법입니다.

      이제 질문에 대한 답변을 드리겠습니다.

      <올>

      할당 연산자는이 두 가지에서 다르게 작동하지 않습니다. RValue에 대한 참조를 추가하고 LValue가이를 가리 키도록하기 만하면됩니다.항상"참조로"(이 용어는 단순한 할당보다 매개 변수 전달과 관련하여 더 의미가 있지만)입니다.

      개체의복사본을 원하면 복사 모듈을 사용하십시오.

      1 지점에서 말했듯이 과제를 수행 할 때 항상 참조를 이동합니다. 요청하지 않으면 복사가 수행되지 않습니다.

    • 답변 # 2

      데이터 모델에서 인용

      와이즈 비즈

      파이썬의 관점에서, 기본 데이터 유형은 기본적으로 C/C ++과 다릅니다. b 를 맵핑하는 데 사용됩니다.  파이썬으로 데이터 타입. 따라서 당분간 토론에서 벗어나 모든 데이터가 대상이며 일부 클래스의 표현이라는 사실을 고려해 봅시다. 모든 객체에는 ID (주소와 유사), 값 및 유형이 있습니다.

      모든 객체는 참조로 복사됩니다. 예를 들어

      a
      

      새 인스턴스를 만드는 유일한 방법은 인스턴스를 만드는 것입니다.

      b
      
      

      이것은 처음에는 복잡하게 들릴지 모르지만 조금 단순화하기 위해 파이썬은 일부 유형을 변경할 수 없게 만들었습니다. 예를 들어

      Objects are Python’s abstraction for data. All data in a Python program is represented by objects or by relations between objects. (In a sense, and in conformance to Von Neumann’s model of a “stored program computer,” code is also represented by objects.)

      를 변경할 수 없습니다 . 슬라이스하고 새 문자열 객체를 만들어야합니다.

      종종 참조로 복사하면 예를 들어 예기치 않은 결과가 나타납니다.

      C/C++  그것은 당신에게 >>> x=20 >>> y=x >>> id(x)==id(y) True >>> 의 2 차원 목록을 만드는 느낌을 줄 수 있습니다 에스. 그러나 실제로는 동일한 목록 객체 [0]의 참조 목록을 만듭니다. 따라서 x [1] [1]을 수행하면 모든 중복 인스턴스가 동시에 변경됩니다.

      복사 모듈은 얕은 인스턴스 대신 객체의 새 인스턴스를 만들기 위해 deepcopy라는 메서드를 제공합니다. 이것은 두 개의 별개의 객체를 갖고 두 번째 예제에서 의도 한대로 개별적으로 조작하려는 경우에 유용합니다.

      예제를 확장하려면

      >>> x=3
      >>> id(x)==id(y)
      False
      >>> x==y
      False
      
      

    • 답변 # 3

      다른 방식으로 작동하지 않습니다. 첫 번째 예에서는a를 변경하여ab가 다른 객체를 참조하도록했습니다. 두 번째 예에서는ab가 여전히 동일한 객체를 참조하지 않았습니다.

      그런데 정수는 불변입니다. 값을 수정할 수 없습니다. 새로운 정수를 만들고 참조를 리 바인드하면됩니다. (당신이 첫 번째 예에서했던 것처럼)

    • 답변 # 4

      당신과 친구를 사귀십시오. 내가 더 이상 그녀를 좋아하지 않기로 결정하면 그녀는 여전히 당신의 친구입니다. 반면에, 그녀에게 선물을 주면 친구가 선물을 받았습니다.

      할당은 파이썬에서 아무 것도 복사하지 않으며, "참조에 의한 복사"는 어색하고 의미가 없습니다 (실제로 여러분의 의견 중 하나를 지적하는 것처럼). 지정하면 변수가 값을 참조하기 시작합니다. 파이썬에는 별도의 "기본 유형"이 없습니다. 그들 중 일부는 내장, string  여전히 수업입니다.

      둘 다경우, 할당은 변수가 오른쪽이 평가하는 모든 것을 참조하게합니다. 여러분이보고있는 행동은 그 은유에 따라 해당 환경에서 정확히 예상되는 것입니다. 당신의 "친구"가 x=[[0]*8]*8 인지  또는 0 속성에 할당하는 것은 변수를 완전히 다른 인스턴스에 다시 할당하는 것과 근본적으로 다르며 이에 따라 동작이 다릅니다.

      진짜 차이는  할당 할 수있는 속성이 없습니다. (이것이 구현이 실제로 당신을 제한하기 위해 약간의 마술을 해야하는 부분입니다.)

      당신은 "참조"라는 두 가지 다른 개념을 혼동하고 있습니다. C ++ >>> class Klasa: def __init__(self, num): self.num = num >>> a = Klasa(2) >>> b = copy.deepcopy(a) >>> print a.num, b.num # prints 2 2 2 2 >>> a.num = 3 >>> print a.num, b.num # prints 3 3 - different! 3 2  할당 될 때 참조 대상이 아닌 참조 된 객체를 내부에서 업데이트하는 마술입니다. 참조가 초기화되면 "재설정"될 수 없습니다. 이것은 대부분의 것들이 가치가있는 언어에서 유용합니다. 파이썬에서 모든 것은 시작에 대한 참조입니다. 파이썬 참조는 항상 유효하고, 널이 아니며, 계산에 사용할 수 없으며, 자동으로 역 참조되는 포인터와 비슷합니다. 지정하면 참조가 다른 것을 완전히 참조하기 시작합니다. 파이썬의 객체는 그렇게 작동하지 않기 때문에 "참조 된 객체를 제자리에서 업데이트"할 수 없습니다. 물론 속성 (액세스 가능한 속성이있는 경우)으로 재생하여 내부 상태를 업데이트 할 수 있지만 해당 속성 자체도 모든 참조입니다.

      int

  • 이전 java - 여러 공백을 포함하는 인수의 Runtimeexec
  • 다음 standards compliance - C ++에서 동적으로 할당되지 않은 가변 길이 배열을 허용하는 이유는 무엇입니까?