Por que não existem modificadores de acesso explícitos no Python:

28

Se 'explícito é melhor que implícito', por que não existem modificadores de acesso explícito no Python: Público, Protegido, Privado etc.?

Eu sei que a idéia é que o programador saiba o que fazer através de uma dica - não é necessário usar 'força bruta'. Mas o "encapsulamento" ou "ocultação de informações" da IMO não é apenas para manter as pessoas afastadas, é uma questão de organização e estrutura: suas camadas de desenvolvimento devem ter escopos e fronteiras autodefinidos e claramente delimitados, assim como os sistemas físicos.

Alguém pode me ajudar aqui com uma explicação sólida sobre por que as restrições de acesso estão implícitas e não explícitas no Python, uma linguagem que, de outra forma, parece quase perfeita?

Edit: Até agora, vi 3 respostas propostas e percebi que existem 2 partes na minha pergunta:

  1. Por que não existem palavras-chave, por exemplo

    private def myFunc(): 
        dostuff....
    

    em vez de IMO, os sublinhados feios e difíceis de digitar. Mas esse não é o ponto importante.

  2. Mais importante:

    Por que esses modificadores de acesso são apenas 'recomendações' ou dicas e não são impostos. Será difícil mudar mais tarde? É muito simples mudar de 'protegido' para 'público' - e se você tem uma cadeia de herança complicada que dificulta, o design é ruim - o design deve ser refinado, em vez de depender de um recurso de linguagem que facilita a escrita código mal estruturado.

    Quando os modificadores de acesso são impostos, seu código é automaticamente compartimentado - você SABE que determinados segmentos estão fora do escopo, portanto você não precisa lidar com eles, exceto se e quando for necessário. E, se o seu design não é bom e você se vê constantemente movendo coisas para dentro e para fora de diferentes escopos, a linguagem pode ajudá-lo a limpar seu ato.

Por mais que eu goste de Python, considero este segundo ponto uma deficiência séria. E ainda tenho que ver uma boa resposta para isso.

Vetor
fonte
possível duplicação dos especificadores de acesso no Python: ... que foi fechada por não ser construtiva.
Frank Shearar 11/07
2
@Frank, este é um pedido novamente dessa pergunta para tentar ser mais construtivo. Fui em frente e excluí a pergunta original.
@ Mark Trapp: Ah, ok. Obrigado pelo esclarecimento. Não vejo como rescindir meu voto para fechar.
117511 Frank Shearar
@Frank Vai envelhecer por conta própria.
Adam Lear
o problema com private def whateveré, que class x: def whatever(self): passé um atalho para class x: pass; x.whatever = lambda self: pass, então, basicamente, você precisaria de um modificator particular de cessão
keppla

Respostas:

22

"Explícito é melhor que implícito" é apenas uma das máximas na filosofia de design do Python. "Simples é melhor que complexo" também existe. E, embora não esteja no Zen de Python, "somos todos adultos concordantes aqui" é outro.

Essa segunda regra é talvez a mais importante aqui. Quando eu desenho uma classe, tenho uma idéia de como ela será usada. Mas não posso prever todos os usos possíveis. Ele pode ser que algum futuro uso do meu código requer acesso às variáveis tenho pensado como privado. Por que devo dificultar - ou até mesmo impossível - acessá-los, se um futuro programador (ou mesmo um futuro eu) precisar deles? A melhor coisa a fazer é marcá-los com um aviso - como observa Joonas, um único prefixo de sublinhado é o padrão - de que eles são internos e podem mudar; mas proibir completamente o acesso parece desnecessário.

Daniel Roseman
fonte
1
"Simples é melhor que complexo" e "Somos todos adultos concordantes aqui" são o motivo pelo qual o Smalltalk não possui modificadores de acesso. Colocar um método na categoria "particular" é uma dica de que você deve pensar três vezes antes de usá-lo, e não mais.
22811 Frank Shearar
@Frank: "Colocar um método na categoria" privado "é uma dica de que você deve pensar três vezes antes de usá-lo, e não mais" Para mim, isso significa simplesmente que não preciso me preocupar com isso quando não estou lidando com isso.
Vector
8
Há uma boa razão para proibir o acesso a membros privados: porque isso pode quebrar os invariantes de classe. Se você não pode escrever membros particulares, não pode ter certeza de que sua classe se comporta corretamente.
Sv16 de
7
"Por que eu deveria dificultar - ou mesmo impossível - acessá-los, se um futuro programador (ou mesmo um futuro eu) precisar deles?" Porque um dos princípios básicos do design é a separação entre a interface (o que um pedaço de código fornece) e a implementação (como ele o fornece). O encapsulamento serve para reduzir a complexidade do código, reduzindo as dependências entre diferentes partes do código. Portanto, público e privado são usados ​​exatamente com o objetivo de manter o código mais simples, permitindo ver apenas o necessário.
Giorgio
3
Não pode diagree mais. Os modificadores de acesso promovem dois dos conceitos provavelmente mais bem compreendidos para reduzir a complexidade em grandes softwares: Encapsulamento e Separação de Preocupações. Deixar de servir nenhum dos dois significa simplesmente que o python não é uma boa linguagem OOP nem adequada para a criação de grandes softwares e não há nada de errado nisso. Mas justificando a ausência de tais recursos com argumentos amadores típicos como "Por que adicionar complexidade quando não é necessário?" está errado.
Daniel Shin
10

Eu suspeitaria que a principal razão para os modificadores de acesso ausentes é a simplicidade

Como você diz, não se trata de manter as pessoas de fora, é sobre a organização. Portanto, o principal ponto de 'privado' é que ele envia uma mensagem aos usuários da sua API 'por favor, não escreva código que dependa disso'.

É trivial dizer 'por convenção, _x ou __x não deve ser usado fora da classe', mas no modelo de objetos dinâmicos do python, seria difícil chegar a uma notação.

class ActiveRow(object):
    def __init__(self, **kwargs):
        for name, value in kwargs.items():
            setattr(self, name, value)

como observar a acessibilidade?

Eu acho que isso foi uma troca. Se você não pode conviver estritamente com isso, sugiro ruby, que possui um nível semelhante de abstração e dinamicidade, mas possui um modelo de objeto que permite a modificação do acesso.

keppla
fonte
8
Eu acho que isso está correto, mas na OMI, é terrível. Para uma linguagem que usa elegância e legibilidade como pontos de venda, escrever __method__ é bastante hediondo e obtuso.
11111 jiggy
2
essa não é a convenção, __x__é 'mágica' (ou seja, métodos chamados para permitir a integração de idiomas, como sobrecarga do operador, iterabilidade etc.). A convenção é _x.
11123 keppla
6
Desculpe, ainda estou tentando entender Python. Estou me esforçando tanto para gostar, mas coisas assim ficam um pouco loucas. Especialmente agora que preciso lembrar o significado de quantos sublinhados um método possui. Para o ponto de vista do OP, parece que modificadores explícitos seriam mais claros. A concisão é ótima, mas não pode superar a clareza. Você gasta 10 vezes mais esforço em manter o código do que em construí-lo.
11111 jiggy
2
Meu exemplo não pretendia mostrar contagens diferentes de sublinhados, o uso de __init__era acidental. O exemplo define algumas propriedades do objeto, que não são conhecidas em tempo de compilação, portanto, um modificador de acesso explícito não ajudaria.
Keppla
5
@ jiggy: "Estou tentando tanto gostar". Eu tentei por 2 anos - então desisti. :-( Parece ser uma linguagem de script que foi hackeada para se comportar um pouco como uma linguagem OOP real. Não consigo imaginar escrever um aplicativo grande e complexo em Python que foi bem projetado e legível. Como você disse: 'Você gasta 10 vezes mais esforço manter o código do que construí-lo '. OOP simples e conceitos seguros de tipo requerem hacks malucos e soluções alternativas
Vetor de
8

A convenção do Python é usar um prefixo de sublinhado para membros protegidos / privados.

Essa convenção, quando seguida, é efetivamente a mesma dos modificadores de acesso, exceto 1) você verá diretamente do nome do membro, seja público ou não, e 2) você pode quebrar o "encapsulamento" se realmente quiser (isso pode ser justificável por exemplo, testes; em alguns outros idiomas, você teria que usar reflexão == mais código).

Por fim, é uma questão de gosto, mas se você puder fazer a mesma coisa (com um pouco mais de flexibilidade) sem palavras-chave especiais, o idioma será menor e o código será mais conciso, o que geralmente é uma coisa boa.

Joonas Pulakka
fonte
2
"se você puder fazer a mesma coisa (com um pouco mais de flexibilidade) sem palavras-chave especiais, o idioma será menor e o código será mais conciso" Na minha opinião, isso geralmente não é verdade. (Mesmo que isso pode ser verdade com o caso especial de modificadores de acesso)
benjaminb