Zen of Python은 작업을 수행 할 수있는 방법은 하나만 있어야한다고 말합니다.하지만 자주 함수를 사용할 때와 메서드를 사용할 때를 결정하는 문제에 직면합니다.
간단한 예인 ChessBoard 객체를 보겠습니다. 보드에서 사용 가능한 모든 합법적 인 King 이동을 얻을 수있는 방법이 필요하다고 가정 해 보겠습니다. ChessBoard.get_king_moves () 또는 get_king_moves (chess_board)를 작성합니까?
내가 살펴본 몇 가지 관련 질문은 다음과 같습니다.
내가 얻은 대답은 대체로 결정적이지 않았습니다.
파이썬은 왜 일부 기능 (예 : list.index ())에 메서드를 사용하고 다른 기능 (예 : len (list))에 대해 사용합니까?
주된 이유는 역사입니다. 함수는 유형 그룹에 대해 일반적이고 메서드가 전혀없는 객체 (예 : 튜플)에서도 작동하도록 의도 된 작업에 사용되었습니다. 파이썬의 기능적 기능을 사용할 때 (map (), apply () et al) 객체의 무정형 컬렉션에 쉽게 적용 할 수있는 함수를 갖는 것도 편리합니다.
실제로 len (), max (), min ()을 내장 함수로 구현하는 것은 실제로 각 유형의 메소드로 구현하는 것보다 코드가 적습니다. 개별 사례에 대해 고민 할 수는 있지만 Python의 일부이며 지금 그러한 근본적인 변경을하기에는 너무 늦었습니다. 대규모 코드 손상을 방지하려면 함수를 유지해야합니다.
흥미롭지 만, 위의 내용은 어떤 전략을 채택해야하는지에 대해 많이 언급하지 않습니다.
이것이 이유 중 하나입니다. 사용자 지정 메서드를 사용하면 개발자가 getLength (), length (), getlength () 등과 같은 다른 메서드 이름을 자유롭게 선택할 수 있습니다. Python은 공통 함수 len ()을 사용할 수 있도록 엄격한 이름 지정을 적용합니다.
약간 더 흥미 롭습니다. 내 생각은 함수가 어떤 의미에서 파이썬 버전의 인터페이스라는 것입니다.
마지막으로, 귀도에서 자신 :
능력 / 인터페이스에 대해 이야기하면서 "불량"특수 메서드 이름 중 일부를 생각하게되었습니다. Language Reference에서 "클래스는 특수한 이름으로 메서드를 정의하여 특수 구문 (예 : 산술 연산 또는 첨자 및 슬라이싱)에 의해 호출되는 특정 연산을 구현할 수 있습니다." 그러나 구문 지원보다는 내장 함수의 이점을 위해 제공되는
__len__
or 와 같은 특수 이름을 가진 이러한 모든 메서드가__unicode__
있습니다. 그 때문에 아마도 인터페이스 기반의 파이썬에서, 이러한 방법은 ABC 방송에 정기적으로 명명 된 방법으로 전환 할__len__
될 것class container: ... def len(self): raise NotImplemented
좀 더 생각해 보면 모든 구문 연산이 특정 ABC에 대해 일반적으로 명명 된 적절한 메서드를 호출
<
object.lessthan
comparable.lessthan
하지 않는 이유를 알 수 없습니다. 예를 들어 " "는 아마도 " "(또는 아마도 " ")를 호출 할 것 입니다. 그래서 또 다른 이점은 파이썬을이 망가진 이름의 이상 함에서 벗어날 수 있다는 것 입니다.흠. 동의하는지 잘 모르겠습니다 (그림 :-).
먼저 설명하고 싶은 "Python 근거"가 두 가지 있습니다.
우선 HCI 이유로 x.len () 대신 len (x)를 선택했습니다 (
def __len__()
훨씬 나중에 나왔습니다). 실제로 두 가지 이유가 있습니다. 두 가지 모두 HCI입니다.(a) 일부 연산의 경우 접두사 표기법이 접미사보다 더 잘 읽습니다. 접두사 (및 중위 어!) 연산은 수학자가 문제에 대해 생각하는 데 도움이되는 표기법을 좋아하는 수학에서 오랜 전통을 가지고 있습니다. 우리는 같은 공식을 다시있는 쉬운 비교
x*(a+b)
에x*a + x*b
원시 OO 표기법을 사용하여 같은 일을하고의 어색함에 있습니다.(b) 내가 무언가의 길이를 요구한다는
len(x)
것을 안다 는 코드를 읽을 때 . 이것은 나에게 두 가지를 알려줍니다. 결과는 정수이고 인수는 일종의 컨테이너입니다. 반대로, 내가 읽을 때x.len()
, 나는 그것이x
인터페이스를 구현하거나 표준을 가진 클래스에서 상속받는 일종의 컨테이너 라는 것을 이미 알고 있어야합니다len()
. 매핑을 구현하지 않는 클래스에get()
또는keys()
메서드가 있거나 파일이 아닌 무언가에 메서드 가있을 때 때때로 우리가 혼란스러워하는 것을 목격하십시오write()
.같은 말을 다른 방식으로 말하면 'len'을 내장 연산으로 봅니다. 나는 그것을 잃고 싶지 않습니다. 그 뜻인지 아닌지는 확실하지 않지만 'def len (self) : ...'는 확실히 평범한 방법으로 강등시키고 싶은 것처럼 들립니다. 나는 그것에 대해 강하게 -1입니다.
제가 설명하겠다고 약속 한 두 번째 파이썬 이론적 근거는 제가
__special__
단순히special
. 나는 클래스가 재정의하기를 원하는 많은 연산, 일부 표준 (예 :__add__
또는__getitem__
), 일부는 그렇게 표준__reduce__
적이 지 않은 연산 (예 : 피클 은 오랫동안 C 코드에서 전혀 지원 하지 않음) 을 예상했습니다 . 이러한 특수 작업이 일반 메서드 이름을 사용하는 것을 원하지 않았습니다. 기존 클래스 또는 모든 특수 메서드에 대한 백과 사전 메모리가없는 사용자가 작성한 클래스는 구현하려는 의도가 아닌 작업을 실수로 정의 할 수 있기 때문입니다. , 비참한 결과를 초래할 수 있습니다. Ivan Krstić는 내가이 모든 것을 쓴 후에 도착한 그의 메시지에서 이것을 더 간결하게 설명했습니다.---Guido van Rossum (홈페이지 : http://www.python.org/~guido/ )
내 이해는 어떤 경우에는 접두사 표기법이 더 의미가 있다는 것입니다 (즉, Duck.quack이 언어 적 관점에서 quack (Duck)보다 더 의미가 있습니다). 다시 말하지만 함수는 "인터페이스"를 허용합니다.
이 경우 Guido의 첫 번째 요점만을 기반으로 get_king_moves를 구현하는 것으로 생각합니다. 그러나 비슷한 푸시 및 팝 메서드로 스택 및 큐 클래스를 구현하는 것과 관련하여 여전히 많은 열린 질문을 남깁니다. 함수 또는 메서드 여야합니까? (여기에서는 푸시-팝 인터페이스를 알리고 싶기 때문에 함수를 추측합니다.)
TLDR : 누군가 함수와 메서드를 사용할시기를 결정하는 전략이 무엇인지 설명 할 수 있습니까?
X.frob
또는X.__frob__
무료 - 서frob
.