2008-09-17 2 views
18

예 :왜 파이썬에서 사전 및 목록에 의해 상속 '렌'함수가 아닙니다

a_list = [1, 2, 3] 
a_list.len() # doesn't work 
len(a_list) # works 

파이썬있는 (매우) 객체입니다 '렌'기능이없는 이유, 이해가 안 지향 객체에 의해 상속됩니다. 플러스 나는 논리적 인 것으로 나에게 나타나기 때문에 계속해서 잘못된 해결책을 시도한다

+0

기능이 상속되지 않습니다. 방법은 있습니다. 어떤 객체의'len' 메소드를 상속 받고 싶습니까? – tzot

+0

len이 __len__ 메서드를 호출하기 때문에이 내용은 중요하지 않으므로 동일한 상속 문제가 계속 적용됩니다. –

+5

@Eli 당신은'__len__' 메쏘드를 의미합니다 - 그래서 SO는 이중 밑줄을 굵게 해석했습니다. =) – MatrixFrog

답변

40

귀도의 설명은 here입니다 : 모든

첫째는, 내가 HCI 이유로 x.len()을 통해 (x)의 렌 선택했다 (DEF __() 나중에 많이했다 __len). 실제적으로 두 가지 얽힌 이유가 있습니다. HCI :

(a) 일부 작업의 경우 접두사 표기법은 postfix 접미사보다 더 읽기 쉽습니다. 접두어 (및 삽입어) 연산은 수학에서 오랜 전통을 지녔으며 시각적으로 도움이되는 표기법을 좋아합니다. 수학자는 문제에 대해 생각합니다. 우리가 x * (a + b)와 같은 수식을 x a + x b로 다시 작성하는 것과 쉬운 점을 원시 OO 표기법을 사용하여 같은 일을하는 것의 어색함과 비교하십시오.

(b) len (x)이라는 코드를 읽을 때 뭔가의 길이를 요구한다는 것을 알고 있습니다. 이것은 두 가지를 말해줍니다. 결과는 정수이고, 인수는 일종의 컨테이너입니다. 반대로, x.len()을 읽을 때 x는 인터페이스를 구현하거나 표준 len()이있는 클래스에서 상속하는 일종의 컨테이너라는 것을 이미 알아야합니다. 맵핑을 구현하지 않는 클래스가 get() 또는 keys() 메소드를 가지고 있거나 파일이 아닌 무언가가 write() 메소드를 가지고있을 때 때때로 우리가 혼란스러워하는 것을 목격하십시오.

다른 말로하면 같은 의미로 'len'이 내장 된 동작으로 간주됩니다. 나는 그것을 잃는 것을 싫어한다./.../

+22

모르는 사람들에게 HCI는 Human-Computer Interface의 약자입니다. 귀도가 "HCI 이유"에 대한 결정을 내렸을 때 그는 코드를 더 읽기 쉽게 만들었다 고 말했습니다. –

+0

@Thomas : Python은 C와 같이 비트 OR로 '|'를 사용합니다. – dan04

+1

Guido가 제네릭 함수를 사용하는 것이 메서드보다 낫다. boggles. :/ –

2

어쩌면 당신은 __len__을 찾고 있을지 모른다. 그 방법이 존재한다면, 렌의 (a)를 호출

>>> class Spam: 
... def __len__(self): return 3 
... 
>>> s = Spam() 
>>> len(s) 
3 
10

그냥하지 않습니다.

당신은, 그러나, 수행 할 수 있습니다

>>> [1,2,3].__len__() 

3 

클래스에 __len__() 방법 len() 마법 일을 만드는 것입니다 추가.

2

음, 사실 길이 방법이있다, 단지 숨겨져 :

>>> a_list = [1, 2, 3] 
>>> a_list.__len__() 
3 

는 len() 내장 함수는 단순히 렌 숨겨진 에 대한 호출에 대한 래퍼 것으로 보인다() 메서드를 호출합니다.

왜 이런 식으로 구현할지 결정한 이유가 확실하지 않습니다.

11

짧은 대답 : 1) 이전 버전과의 호환성 및 2) 실제와 관련하여 차이가 충분하지 않습니다. 자세한 설명을 보려면 계속 읽으십시오.

이러한 작업에 대한 관용적 인 파이썬 접근법은 직접 호출 할 수없는 특수한 방법입니다. 예를 들어 x + y이 자신의 클래스에서 작동하도록하려면 __add__ 메서드를 작성합니다.int(spam)이 맞춤 클래스를 올바르게 변환하도록하려면 __int__ 메소드를 작성하십시오. len(foo)이 올바른지 확인하려면 __len__ 메소드를 작성하십시오.

이것은 항상 일들이 파이썬에서 있었던 것과 같습니다. 몇 가지 사항에 대해서는 많은 의미가 있다고 생각합니다. 특히 이것은 연산자 오버로딩을 구현하는 합리적인 방법처럼 보입니다. 나머지는 다른 언어들이 동의하지 않는다. 루비에서는 int(spam) 대신 직접 spam.to_i을 호출하여 정수로 변환합니다.

여러분은 파이썬이 매우 객체 지향적 인 언어라는 것과 그 객체를 길이를 얻기 위해 외부 함수를 호출해야한다는 것이 이상한 것처럼 보입니다. 반면에 len(silly_walks)은 더 이상 silly_walks.len()보다 번거롭지 않으며 Guido는 실제로 (http://mail.python.org/pipermail/python-3000/2006-November/004643.html)를 선호한다고 말했습니다.

+3

아 ... 이것은 마침내 그것을 전부 이해했다. len()은 실제로 함수라는 연산자에 가깝습니다. – Nate

5

이렇게하면 나머지 언어와 더 잘 어울립니다. 파이썬의 관례는 오브젝트에 특정 메소드를 추가하여 (예 : 특정 기본 클래스에서 파생되는 것보다는) 특정 기능을 갖도록하는 것입니다. 그것이이 __iter__ 방법

  • 은 []는 __getitem____setitem__ 경우와 액세스를 지원하는 경우 그것이 __call__ 방법
  • 반복 가능한있는 경우 예를 들어, 객체는

    • 호출이다. 이 특별한 방법
    • ...

    하나는 len()에 액세스 할 수있는 길이 있습니다 __len__입니다.

  • 관련 문제