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.lessthancomparable.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.