program tip

Python에서 한 변수의 값을 다른 변수에 할당하면 어떻게됩니까?

radiobox 2020. 10. 21. 07:54
반응형

Python에서 한 변수의 값을 다른 변수에 할당하면 어떻게됩니까?


이것은 파이썬을 배우는 두 번째 날입니다 (C ++와 OOP의 기초를 알고 있습니다.). 파이썬의 변수에 대해 약간의 혼란이 있습니다.

현재 내가 이해하는 방법은 다음과 같습니다.

파이썬 변수는 객체 (변경 가능하거나 변경 불가능한)에 대한 참조 (또는 포인터?)입니다. 와 같은 것이 있으면 num = 5불변 객체 5가 메모리 어딘가에 생성되고 이름-객체 참조 쌍이 num특정 네임 스페이스에 생성됩니다. 가있을 때 a = num아무것도 복사되지 않지만 이제 두 변수가 동일한 객체를 참조 a하고 동일한 네임 스페이스에 추가됩니다.

이것이 제 책인 Automate the boring stuff with Python 에서 저를 혼란스럽게합니다. 초보 책이므로 객체, 네임 스페이스 등을 언급하지 않고 다음 코드를 설명하려고합니다.

>>> spam = 42
>>> cheese = spam
>>> spam = 100
>>> spam
100
>>> cheese
42

그것이 제공하는 설명은 C ++ 책의 설명과 똑같습니다. 객체에 대한 참조 / 포인터를 다룰 때 만족스럽지 않습니다. 따라서이 경우 정수가 불변이므로 세 번째 줄에서 spam완전히 새로운 포인터 / 참조가 메모리의 다른 위치에 할당됩니다. 즉, 처음에 가리키는 메모리가 수정되지 않았습니다. 따라서에서 cheese참조하는 초기 객체를 참조했습니다 spam. 이것이 올바른 설명입니까?


C ++ 개발자는 Python 변수를 포인터로 생각할 수 있습니다.

따라서를 작성할 때 spam = 100이는 이전에 개체 42를 가리 키던 "포인터를 할당"하여 개체를 가리킴을 의미 합니다 100.

이전에, cheese같은 객체에 지점에 할당 spam할 일이있는 지적 42그 시간에. 수정하지 않았 cheese으므로 여전히을 가리 킵니다 42.

이 경우 불변성은 포인터 할당이 가리키는 개체에 대해 아무것도 변경하지 않기 때문에이 경우와 관련이 없습니다.


내가 보는 방식은 언어에 대한 다른 견해입니다.

  • "언어 변호사"관점.
  • "실용적인 프로그래머"관점.
  • "구현 자"관점.

언어 변호사의 관점에서 파이썬 변수는 항상 객체를 "가리 킵니다". 그러나 Java 및 C ++와 달리 == <=> = 등의 동작은 변수가 가리키는 객체의 런타임 유형에 따라 다릅니다. 또한 파이썬에서 메모리 관리는 언어에 의해 처리됩니다.

실용적인 프로그래머 관점에서 우리는 정수, 문자열, 튜플 등이 직선 값이 아니라 불변 * 객체라는 사실을 무관 한 세부 사항으로 취급 할 수 있습니다. 예외는 많은 양의 숫자 데이터를 저장할 때 작은 객체에 대한 참조로 가득 찬 배열로 끝나는 유형이 아닌 값을 직접 저장할 수있는 유형 (예 : numpy 배열)을 사용할 수 있다는 것입니다.

구현 자의 관점에서 대부분의 언어에는 지정된 동작이 올바른 경우 실제로 내부에서 작업이 수행되는 방식에 관계없이 구현이 올바른 것과 같은 일종의 as-if 규칙이 있습니다.

그렇습니다. 언어 변호사의 관점에서 귀하의 설명은 정확합니다. 당신의 책은 실용적인 프로그래머 관점에서 옳습니다. 구현이 실제로 수행하는 작업은 구현에 따라 다릅니다. cpython에서 정수는 새로 생성되지 않고 캐시 풀에서 작은 값의 정수를 가져 오지만 실제 객체입니다. 다른 구현 (예 : pypy 및 jython)이 무엇을하는지 잘 모르겠습니다.

* 여기에서 변경 가능한 객체와 변경 불가능한 객체의 차이점에 유의하십시오. 변경 가능한 객체를 사용하는 경우 다른 코드가 변경 될 수 있으므로 "값처럼"취급하는 데주의해야합니다. 불변 객체를 사용하면 그러한 문제가 없습니다.


포인터로 변수를 더 많거나 적을 수 있다는 것은 정확합니다. 그러나 예제 코드는 이것이 실제로 어떻게 작동 하는지 설명 하는 데 크게 도움이 될 것 입니다.

첫째, 우리는 id기능 을 많이 활용할 것입니다 .

객체의 "ID"를 반환합니다. 이것은 수명 동안이 객체에 대해 고유하고 상수가 보장되는 정수입니다. 수명이 겹치지 않는 두 개체는 동일한 id () 값을 가질 수 있습니다.

컴퓨터에서 다른 절대 값을 반환 할 가능성이 있습니다.

이 예를 고려하십시오.

>>> foo = 'a string'
>>> id(foo) 
4565302640
>>> bar = 'a different string'
>>> id(bar)
4565321816
>>> bar = foo
>>> id(bar) == id(foo)
True
>>> id(bar)
4565302640

다음을 확인할 수 있습니다.

  • 원래 foo / bar는 다른 객체를 가리 키기 때문에 다른 ID를 갖습니다.
  • bar가 foo에 할당되면 이제 ID가 동일합니다. 이것은 둘 다 C ++ 포인터를 만들 때 볼 수있는 메모리의 동일한 위치를 가리키는 것과 비슷합니다.

foo의 값을 변경하면 다른 ID에 할당됩니다.

>>> foo = 42
>>> id(foo)
4561661488
>>> foo = 'oh no'
>>> id(foo)
4565257832

흥미로운 점은 정수가이 기능을 최대 256까지 암시 적으로 갖는다는 것입니다.

>>> a = 100
>>> b = 100
>>> c = 100
>>> id(a) == id(b) == id(c)
True

그러나 256 이상은 더 이상 사실이 아닙니다.

>>> a = 256
>>> b = 256
>>> id(a) == id(b)
True
>>> a = 257
>>> b = 257
>>> id(a) == id(b)
False

그러나 할당 ab전에 같이 참으로 ID를 동일하게 유지됩니다

>>> a = b
>>> id(a) == id(b)
True

Python은 참조에 의한 전달 또는 값에 의한 전달이 아닙니다. 파이썬 변수는 포인터가 아니며 참조가 아니며 값이 아닙니다. 파이썬 변수는 이름 입니다.

동일한 구문 유형이 필요한 경우 "통과 별 별칭"으로 생각하거나 "개체 별 전달"로 생각하십시오. 변경 가능한 경우이를 나타내는 모든 변수에서 동일한 객체를 변경할 수 있지만 변수 (별칭)는 해당 변수 하나만 변경합니다.

If it helps: C variables are boxes that you write values into. Python names are tags that you put on values.

A Python variable's name is a key in the global (or local) namespace, which is effectively a dictionary. The underlying value is some object in memory. Assignment gives a name to that object. Assignment of one variable to another variable means both variables are names for the same object. Re-assignment of one variable changes what object is named by that variable without changing the other variable. You've moved the tag but not changed the previous object or any other tags on it.

In the underlying C code of the CPython implementation, every Python object is a PyObject*, so you can think of it as working like C if you only ever had pointers to data (no pointers-to-pointers, no directly-passed values).

you could say that Python is pass-by-value, where the values are pointers… or you could say Python is pass-by-reference, where the references are copies.


When you run spam = 100 python create one more object in the memory but not change existing. so you still have pointer cheese to 42 and spam to 100


What is happening in spam = 100 line is replacement of previous value (pointer to object of type int with value 42) with another pointer to another object (type int, value 100)


As @DeepSpace mentioned in the comments, Ned Batchelder does a great job demystifying variables (names) and assignments to values in a blog, from which he delivered a talk at PyCon 2015, Facts and Myths about Python names and values. It can be insightful for Pythonistas at any level of mastery.


When you store spam = 42 , it creates an object in the memory. Then you assign cheese = spam , It assigns the object referenced by spam to cheese. And finally, when you change spam = 100, it changes only spam object. So cheese = 42.

참고URL : https://stackoverflow.com/questions/45053461/what-happens-when-you-assign-the-value-of-one-variable-to-another-variable-in-py

반응형