왜“자기”가 필요한가요? 파이썬에서 인스턴스 변수를 참조합니까?


13

Java, Ruby, Haskell 및 Python과 같은 여러 언어로 프로그래밍했습니다. 다른 프로젝트로 인해 하루에 여러 언어로 전환해야합니다. 이제 문제는 self파이썬에서 함수 정의의 첫 번째 매개 변수가 동일한 객체에서 메서드를 호출하는 것과 마찬가지로 쓰는 것을 잊어 버리는 경우가 많습니다 .

즉, 나는이 파이썬 접근 방식에 상당히 놀랐습니다. 기본적으로 우리는 Java 및 Ruby와 같은 언어에서 현재 객체의 변수를 자동으로 참조하여 작업을 단순화하기 위해 더 많이 입력해야합니다.

내 질문은 왜 이것이 self필요한가? 그것은 순수한 스타일 선택입니까, 아니면 파이썬이 selfJava와 C ++에서 생략 할 수 있는 방식 을 생략 할 수없는 이유가 this있습니까?



1
@gnat은 이제 전문가 들이며 진지하게 좋은 질문은 며칠 이후 저를 괴롭히는 것입니다.
vivek

2
이 질문은 stackoverflow.com/questions/2709821/…의해 철저히 다루어졌습니다 .
David Arno

내 이해는 그것이 첫 번째 인수로 구조체에 포인터를 전달하는 C 스타일을 기반으로한다는 것입니다.
Dannnno

@staticmethod메소드 선언 전에 작성 하여 오류를 억제합니다 (정보 용이며 권장하지 않음)
Yash

답변:


23

1) 왜 self메소드 서명에서 명시적인 매개 변수로 필요합니까?

방법은 함수이고 foo.bar(baz)단지 구문 설탕 이기 때문 입니다 bar(foo, baz). 클래스는 일부 값이 함수 인 사전 일뿐입니다. (생성자도 함수일 뿐이 new므로 파이썬이 필요하지 않습니다. ) 파이썬은 객체가 더 간단한 컴포넌트로 만들어 졌다는 것을 명시 적으로 말할 수 있습니다. 이것은 "명시적인 것이 묵시적인 것보다 낫다"라는 철학에 따른 것입니다.

반대로 Java 객체에서는 실제로 마술이며 언어의 간단한 구성 요소로 축소 될 수 없습니다. Java에서 (적어도 Java 8까지) 함수는 항상 객체가 소유 한 메소드이며,이 소유권은 언어의 정적 특성으로 인해 변경할 수 없습니다. 따라서 무엇을 this의미 하는지 모호하지 않기 때문에 암시 적으로 정의하는 것이 좋습니다.

JavaScript는 thisJava와 같이 암시 적이 지만 Python과 같은 객체와 별도로 함수가 존재할 수 있는 언어의 예입니다 . 이것은 함수가 다른 컨텍스트에서 전달되고 호출 될 때 참조되는 것에 대해 많은 혼란을 초래 this합니다. 많은 본능적으로 this함수의 본질적인 속성을 참조해야하지만 실제로는 함수가 호출되는 방식에 의해 순수하게 결정됩니다. this파이썬에서와 같이 명시 적 매개 변수로 사용하면 혼란을 덜 줄 수 있다고 생각 합니다.

명시 적 self매개 변수 의 다른 장점 :

  • 데코레이터는 다른 기능을 감싸는 기능입니다. 메소드는 단지 함수이기 때문에 데코레이터는 메소드에서 잘 작동합니다. 어떤 종류의 암시 적 자아가 있다면, 데코레이터는 메소드에서 투명하게 작동하지 않습니다.

  • 클래스 메소드와 정적 메소드는 인스턴스 매개 변수를 사용하지 않습니다. 클래스 메소드클래스 를 첫 번째 인수 (일반적으로 cls)로 사용합니다. 명시 적 self또는 cls매개 변수를 사용하면 진행중인 작업과 메서드에서 액세스 할 수있는 대상이 훨씬 명확 해집니다.

2) 왜 인스턴스 변수는 항상 "로 한정되어야 self.합니까? "

Java에서는 멤버 변수에 " this." 를 접두사로 붙일 필요는 없지만 Python에서는 " self."가 항상 필요합니다. 그 이유는 파이썬에 변수 선언을위한 명시적인 구문이 없기 때문에 x = 7새로운 로컬 변수를 선언해야하는지 또는 멤버 변수에 할당해야하는지 알 수있는 방법이 없기 때문입니다 . 지정 self.하면이 모호성이 해결됩니다.


self.Java와 같은 암시 적 멤버 변수 참조 는 범위 지정 규칙과 기본적으로 호환되지 않으며 명시 적으로 지정해야 할 때 매개 변수에 대한 암시가 더 이상 의미가 없습니다.
Jan Hudec

@ JanHudec : 좋아, 포인트. 나는 그것을 대답에 추가했다.
JacquesB

6

크로스 사이트 복제본에서 AFAIK가 실제로 다루어지지 않은 간단한 이유가 있습니다. 파이썬은 절차 언어로 시작했습니다. 또한 절차 언어 인 ABC를 기반으로했습니다.

나중에 Object-Orientation이 추가되었고 Guido van Rossum이 추가되었을 때 Python의 디자인을 단순하게 유지하기 위해 가능한 최소한의 기능을 추가하려고했습니다. 파이썬에는 이미 dicts와 함수가 있었기 때문에 객체가 단순히 dict슬롯 수 있고 클래스가 단순히 dict함수 수일 때 언어에 완전히 새로운 것을 추가하는 이유는 무엇 입니까? 메소드는 단일 식별 인수를 닫는 부분적으로 적용되는 함수로 해석 될 수 있습니다. 그리고 이것이 정확하게 메소드가 파이썬에서 구현되는 방식입니다. 그것들은 추가로 구별되는 인수를받는 함수 일뿐입니다.


나는 파이썬이 OO를 지원했으며 첫 번째 릴리스 버전에서 클래스와 상속을 받았다고 생각합니다. 적어도 이것은 위키 백과가 알려주는 것입니다. 그러나 반 로섬 (Van Rossums)은 처음에 언어를 설계하는 과정을 설명했듯이 진행했을 수 있습니다.
JacquesB


링크 주셔서 감사합니다, 이것은 정말 흥미로운 독서입니다.
JacquesB

2

위의 답변을 바탕 으로이 주제에 대한 귀도의 독자적인 견해 를 읽은 결론은 다음과 같습니다 .

큰 아이디어

함수는 파이썬에서 중요한 빌딩 블록입니다 (또는 우리가 유일하게 말해야합니다). 실제로 함수를 사용하여 OOP를 에뮬레이트합니다.

클래스가 함수 사전 일 뿐이므로 런타임에 모든 함수를 클래스에 첨부 할 수 있습니다. 기본적으로 이것은 런타임에 함수를 던져서 Monkey Patching 과 같은 것들을 할 수 있기 때문입니다 . 여기서, self파라미터는 파라 메트릭 다형성을 지원.


1
답변이 고품질 답변 일 경우 자체 답변이 권장 됩니다. 여기에 귀하의 답변을 다른 답변과 비교할 때 왜 이것을 추가해야한다고 생각하는지 궁금합니다. 다른 답변은 답변이 수행하는 것보다 더 깊이 들어가고 자세한 내용을 추가합니다.

1
@ GlenH7 대답은 내가 올 수 없을 때마다 모든 사람의 대답을 계속해서 다시 읽을 수 있기 때문에 단지 참조 용이었습니다. 품질과 관련하여 약간의 정보가 오해의 소지가 있는지 알려주십시오. 어쨌든 나는 일반적으로 답변을 수락하기 위해 2-3 일을 기다립니다.
vivek

다운 투표는 저렴한 통화가되고 있으며 여기있는 모든 사람들은 그 의미를 모른 채 양손으로 통화하고 있습니다. 누군가가 여기에 오면 투표에 응한이 답변이 잘못되었다는 것을 알 수 있습니다!
vivek
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.