Eu sei que python tem uma len()
função que é usada para determinar o tamanho de uma string, mas eu queria saber por que não é um método do objeto string.
Atualizar
Ok, eu percebi que estava embaraçosamente enganado. __len__()
é realmente um método de um objeto string. Parece estranho ver código orientado a objetos em Python usando a função len em objetos de string. Além disso, também é estranho ver __len__
como o nome em vez de apenas len.
len
. Eles acham que é mais fácil forçar as pessoas a implementar.__len__
do que forçar as pessoas a implementar.len()
. É a mesma coisa, e um parece muito mais limpo. Se o idioma tiver um POO__len__
, o que o mundo está fazendolen(..)
__iter__
, ou apenas__getitem__
, eiter(x)
funcionará de qualquer maneira. Você pode criar um objeto utilizável em contexto booleano com__bool__
ou__len__
, ebool(x)
funcionará de qualquer maneira. E assim por diante. Acho Armin explica isso razoavelmente bem no pós-mas ligada, mesmo que ele não fez, chamando Python idiota por causa de uma explicação fora por um cara que é muitas vezes publicamente em desacordo com os devs centrais não seria exatamente justo ...zip
é uma função de nível superior, não umzip_with
método. E assim por diante. Só porque tudo é um objeto não significa que ser um objeto é a coisa mais importante sobre cada coisa.A resposta de Jim para essa pergunta pode ajudar; Eu copio aqui. Citando Guido van Rossum:
fonte
Existe um
len
método:fonte
Python é uma linguagem de programação pragmática, e as razões para
len()
ser uma função e não um método destr
,list
,dict
etc. são pragmáticos.A
len()
função interna lida diretamente com os tipos internos: a implementação do CPythonlen()
na verdade retorna o valor doob_size
campo naPyVarObject
estrutura C que representa qualquer objeto interno de tamanho variável na memória. Isso é muito mais rápido do que chamar um método - nenhuma pesquisa de atributo precisa acontecer. Obtendo o número de itens em uma coleção é uma operação comum e deve trabalhar de forma eficiente para tais tipos básicos e diversos comostr
,list
,array.array
etc.No entanto, para promover consistência, ao se aplicar
len(o)
a um tipo definido pelo usuário, o Python chamao.__len__()
como fallback.__len__
,__abs__
e todos os outros métodos especiais documentados no Python Data Model facilitam a criação de objetos que se comportam como os incorporados, habilitando as APIs expressivas e altamente consistentes que chamamos de "Pythonic".Ao implementar métodos especiais, seus objetos podem oferecer suporte à iteração, sobrecarregar operadores de infixos, gerenciar contextos em
with
blocos etc.Uma segunda razão, apoiada em citações de Guido van Rossum como essa , é que é mais fácil ler e escrever do
len(s)
ques.len()
.A notação
len(s)
é consistente com operadores unários com notação de prefixo, comoabs(n)
.len()
é usado com mais frequênciaabs()
e merece ser tão fácil de escrever.Também pode haver uma razão histórica: na linguagem ABC que precedeu o Python (e foi muito influente em seu design), havia um operador unário escrito como o
#s
que significavalen(s)
.fonte
fonte
Há ótimas respostas aqui e, antes de dar as minhas, gostaria de destacar algumas das gemas (sem trocadilhos de rubi) que li aqui.
len
é realmente um objeto. Ruby, por outro lado, não possui funções de primeira classe. Portanto, olen
objeto de função possui seus próprios métodos que você pode inspecionar executandodir(len)
.Se você não gosta da maneira como isso funciona em seu próprio código, é trivial reimplementar os contêineres usando seu método preferido (veja o exemplo abaixo).
fonte
Você também pode dizer
Usando o Python 2.7.3.
fonte
len
A função já foi mencionada nas respostas anteriores. Qual é o sentido dessa "resposta", então?Algo está faltando no restante das respostas aqui: a
len
função verifica se o__len__
método retorna um resultado não negativoint
. O fato delen
ser uma função significa que as classes não podem substituir esse comportamento para evitar a verificação. Como tal,len(obj)
fornece um nível de segurança queobj.len()
não pode.Exemplo:
Obviamente, é possível "substituir" a
len
função reatribuindo-a como uma variável global, mas o código que faz isso é muito mais obviamente suspeito do que o código que substitui um método em uma classe.fonte
Não faz?
fonte