Tenho programado em várias linguagens como Java, Ruby, Haskell e Python. Eu tenho que alternar entre vários idiomas por dia devido a diferentes projetos nos quais trabalho. Agora, o problema é que muitas vezes esqueço de escrever self
como o primeiro parâmetro nas definições de função no Python. O mesmo ocorre com a chamada de métodos no mesmo objeto.
Dito isto, estou bastante impressionado com essa abordagem do Python. Basicamente, precisamos digitar mais para realizar as tarefas, nas linguagens como Java e Ruby, as coisas são simplificadas pela referência automática às variáveis no objeto atual.
Minha pergunta é por que isso é self
necessário? É uma escolha puramente de estilo ou existe uma razão pela qual o Python não pode deixar você omitir self
a maneira como Java e C ++ o deixam this
?
@staticmethod
antes da declaração do método, suprime o erro (apenas para informações e também não é recomendado)Respostas:
1) Por que é
self
exigido como parâmetro explícito nas assinaturas de métodos?Porque métodos são funções e
foo.bar(baz)
são apenas açúcar sintático parabar(foo, baz)
. Classes são apenas dicionários em que alguns dos valores são funções. (Construtores também são apenas funções, e é por isso que o Python não precisanew
). Você pode dizer que o Python torna explícito que os objetos são criados a partir de componentes mais simples. Isso está de acordo com a filosofia "explícito é melhor que implícito".Por outro lado, em Java, os objetos são realmente mágicos e não podem ser reduzidos a componentes mais simples da linguagem. Em Java (pelo menos até Java 8), uma função é sempre um método de propriedade de um objeto, e essa propriedade não pode ser alterada devido à natureza estática da linguagem. Portanto, não há ambiguidade sobre o que
this
se refere, portanto, faz sentido tê-lo definido implicitamente.JavaScript é um exemplo de uma linguagem implícita
this
como Java, mas onde funções podem existir separadamente de objetos como em Python. Isso leva a muita confusão sobre o quethis
se refere a quando funções são passadas e chamadas em diferentes contextos. Muitos pensam instintivamente quethis
devem se referir a alguma propriedade intrínseca da função, enquanto na verdade é puramente determinada pela maneira como a função é chamada. Eu acredito que terthis
como parâmetro explícito como em Python tornaria isso muito menos confuso.Alguns outros benefícios do
self
parâmetro explícito :Decoradores são apenas funções que envolvem outras funções. Como os métodos são apenas funções, os decoradores funcionam tão bem quanto os métodos. Se houvesse algum tipo de identidade implícita, os decoradores não trabalhariam de maneira transparente nos métodos.
Métodos de classe e métodos estáticos não aceitam um parâmetro de instância. Os métodos de classe usam uma classe como o primeiro argumento (normalmente chamado
cls
). O parâmetro explícitoself
oucls
torna muito mais claro o que está acontecendo e o que você tem acesso no método.2) Por que as variáveis de instância sempre devem ser qualificadas com "
self.
?Em Java, você não precisa prefixar variáveis de membro com "
this.
", mas em Python "self.
" é sempre necessário. O motivo é que o Python não possui uma sintaxe explícita para declarar variáveis; portanto, não há como saber sex = 7
deve declarar uma nova variável local ou atribuir a uma variável membro. A especificaçãoself.
resolve essa ambiguidade.fonte
self.
, como Java) é fundamentalmente incompatível com as regras de escopo e, quando você precisa ser explícito lá, estar implícito no parâmetro não faz mais tanto sentido.Há uma razão bastante simples pela qual o AFAIK não foi realmente abordado na duplicata entre sites, nem aqui: o Python começou como uma linguagem processual. Foi baseado no ABC, também uma linguagem processual.
A Orientação a Objetos foi adicionada mais tarde e, quando foi adicionado, Guido van Rossum queria adicionar a quantidade mínima de recursos possível, a fim de manter o design do Python simples. O Python já tinha
dict
s e funções, então, por que adicionar algo inteiramente novo à linguagem, quando um objeto pode simplesmente ser umdict
dos slots e uma classe pode simplesmente ser umadict
das funções? Um método pode ser interpretado como uma função parcialmente aplicada que fecha sobre um único argumento distinto. E é exatamente assim que os métodos são implementados no Python: eles não são. São apenas funções que recebem um argumento distinto extra.fonte
Aqui estão minhas conclusões com base nas respostas acima e na leitura das divagações do Guido sobre este tópico:
A grande ideia
As funções são os blocos de construção importantes no Python (ou deveríamos dizer o único); na verdade, estamos meio que emulando o OOP usando funções.
Dado que uma classe nada mais é que um dicionário de funções, podemos anexar qualquer função a qualquer classe em tempo de execução. Basicamente, devido a essa necessidade de lançar as funções em tempo de execução, podemos fazer coisas como Monkey Patching . Aqui, o
self
parâmetro que suporta o polimorfismo paramétrico.fonte