Pergunta

Existem para Python , mas controlo do tempo de compilação tendem a ser diametralmente oposto ao tempo de execução de ligao filosofia que abraços Python. É de possível para embrulhar o interpretador Python padrão com uma ferramenta de análise estática para impor algum " use strict "-como restrições, mas não vemos qualquer adopção generalizada de tal coisa.

Existe algo sobre Python que faz "use strict" comportamento desnecessário ou especialmente indesejável?

Como alternativa, é a "utilização rigorosa" comportamento desnecessário em Perl, apesar da sua adopção generalizada?

Nota: por "necessário" Quero dizer "praticamente necessário", não é estritamente necessário. Obviamente você pode gravar Perl sem "use strict", mas (pelo que eu vi) a maioria dos programadores Perl do usá-lo.

Nota: necessidade intérprete-wrapper O Python não requerem "use strict", como restrições - você poderia usar um pseudo-pragma semelhante a "usar estrita" que seria ignorado pelo intérprete normais . Eu não estou falando sobre a adição de um recurso de nível de linguagem.


Update: Explicando que "use strict" faz em Perl por comentários. (Link para a documentação oficial é no primeiro parágrafo.)

O "use strict" directiva tem três componentes distintos, dos quais apenas dois são realmente interessantes:

  • usar vars estritas: verificações Estaticamente escopo léxico de uso variável no seu programa. (Tenha em mente que, em Python, há basicamente apenas uma margem global e alcance local). Muitos linters Python verificar se há esse tipo de coisa. Uma vez que é a análise apenas estática que eles podem fazer, os linters supor que você use o escopo lexical simples e avisá-lo sobre as coisas que aparecem errado nesse sentido até que você dizer-lhes para se calar; i.

    FOO = 12
    foo += 3
    

    Se você não está fazendo fantasia nada com seus namespaces isso pode ser útil para verificar se há erros de digitação.

  • use strict refs: Previne namespace simbólica dereferencing. analógico mais próximo do Python está usando locals() e globals() para fazer pesquisa de ligação e identificador simbólico.

  • usar subs rigorosas:. Não analógica real em Python

Foi útil?

Solução

"a filosofia de ligação run-time que abraços Python ... faz "use strict" comportamento desnecessário [e] especialmente indesejável"

resumo Muito bom. Obrigado.

Isso é essencialmente isso. ferramentas de análise estática não ajudam Python suficiente para valer a pena.


Editar

"Eu estou pedindo-nos para a introspecção em por não precisamos dele e, relativamente, por programadores Perl acho que eles precisam fazer isso."

A razão pela qual é precisamente a razão que você já deu. Nós não precisamos dele porque ele não ajuda. Claramente, você não gosta que a resposta, mas não há muito mais a ser dito. Em tempo de compilação ou pré-compilação tempo verificando simplesmente não ajuda.

No entanto, uma vez que você tomou o tempo para a pergunta novamente, eu vou fornecer mais evidências para a resposta que você já deu.

Eu escrevo Java quase tanto quanto eu escrevo Python. tipo estático verificação do Java não impede que quaisquer problemas de lógica; não facilitar o cumprimento dos requisitos de desempenho; ele não ajudar a atender os casos de uso. Ele nem sequer reduzir o volume de testes de unidade.

Enquanto a verificação de tipo estático faz detectar o mau uso ocasional de um método, você descobrir isso tão rapidamente em Python. Em Python você encontrá-lo em tempo de teste de unidade, porque não vai funcionar. Nota:. Não estou dizendo que tipos errados são encontrados com lotes de testes de unidade inteligente, eu estou dizendo questões tipo mais erradas são encontrados através de exceções não tratadas onde a coisa simplesmente não vai correr para longe o suficiente para chegar a afirmações de teste

A razão pela qual é Pythonistas não perder tempo com verificação estática é simples. Nós não precisa dele. Ela não oferece qualquer valor. É um nível de análise que não tem nenhum benefício econômico. Não faz-me mais capaz de resolver os problemas reais que pessoas reais estão tendo com seus dados reais.

Olhe para os mais populares perguntas SO Python que são língua (não domínio do problema ou biblioteca) relacionados.

Existe alguma diferença entre "foo é None" e "foo == None" -? == vs. is. Nenhuma verificação estática pode ajudar com isso. Além disso, veja Existe uma diferença entre `==` e ` is` em Python?

O que ** (estrela dupla) e * (asterisco) para fazer parâmetros -? *x dá uma lista, **x dá um dicionário. Se você não sabe isso, o seu programa morre imediatamente quando você tentar fazer algo impróprio para esses tipos. "E se o seu programa nunca faz nada 'inadequado'". Em seguida, seu programa funciona. 'Nuff disse.

Como posso representar um 'Enum' em ? Python - este é um apelo para algum tipo de tipo de domínio limitado. Uma classe com valores de nível de classe praticamente faz esse trabalho. "E se alguém muda a atribuição". Fácil de construir. Substituir __set__ para levantar uma exceção. Sim verificação estática pode detectar isso. Não, isso não acontece na prática que alguém fica confuso sobre uma constante enum e uma variável; e quando o fazem, é fácil de detectar em tempo de execução. "E se a lógica nunca é executado". Bem, isso é má concepção e teste de unidade pobres. Jogando um erro do compilador e colocando em lógica errada que nunca testados não melhor do que o que acontece em uma linguagem dinâmica quando nunca é testado é.

Generator Expressões vs. compreensão da lista - verificação estática não ajudar a resolver esta questão.

Por que 1 +++ 2 = 3 -? verificação estática não iria manchar este 1 +++ 2 em C é perfeitamente legal, apesar de toda a verificação de que o compilador Não é o.. mesma coisa em Python como é em C, mas apenas como legal. E assim como confuso.

Lista de listas de alterações refletidas através sublists inesperadamente - - Isso é inteiramente conceitual. verificação estática não pode ajudar a resolver este problema. O equivalente Java também compilar e se comportar mal.

Outras dicas

Bem, eu não sou muito de um programador python, mas eu diria que a resposta é 'sim'.

Qualquer linguagem dinâmica que permite criar uma variável com qualquer nome, a qualquer momento, poderia usar um pragma 'rigorosa'.

vars estritos (uma das opções para estrita em Perl, 'use strict' transforma-los todos de uma vez) em Perl requer que todas as variáveis ??são declaradas antes de serem usadas. O que significa que este código:

my $strict_is_good = 'foo';
$strict_iS_good .= 'COMPILE TIME FATAL ERROR';

Gera um erro fatal em tempo de compilação.

Eu não sei de uma maneira de obter Python para rejeitar este código em tempo de compilação:

strict_is_good = 'foo';
strict_iS_good += 'RUN TIME FATAL ERROR';

Você receberá uma exceção de tempo de execução que strict_iS_good é indefinido. Mas apenas quando o código é executado. Se o seu conjunto de testes não tem cobertura de 100%, você pode facilmente enviar este bug.

Toda vez que eu trabalho em uma linguagem que não tem este comportamento (PHP por exemplo), eu fico nervoso. Eu não sou um datilógrafo perfeito. Um simples, mas difícil de detectar, erro de digitação pode causar o seu código para falhar de maneiras que podem ser difíceis de rastrear.

Assim, para reiterar, YES Python poderia usar um pragma 'rigorosa' para ativar verificações de tempo de compilação para as coisas que podem ser verificados em tempo de compilação. Eu não consigo pensar em quaisquer outros controlos para adicionar, mas um programador melhor Python provavelmente poderia pensar em algum.

Nota eu foco sobre o efeito pragmático de stict vars em Perl, e estou passando por cima de alguns detalhes. Se você realmente quer saber todos os detalhes consulte o perldoc para estrita .

Update: As respostas a alguns comentários

Jason Baker : damas estáticos como pylint são úteis. Mas eles representam um passo extra que pode ser e muitas vezes é ignorada. Construir algumas verificações básicas para o compilador garante que estas verificações são executadas de forma consistente. Se estas verificações são controláveis ??por um pragma, mesmo a acusação relativa ao custo dos controlos torna-se discutível.

POPCNT : Eu sei que python irá gerar uma exceção de tempo de execução. Eu disse isso. Eu defendo tempo de compilação verificação sempre que possível. Por favor, releia o post.

mpeters : Não análise de computador de código pode encontrar todos os erros - isso equivale a resolver o problema da parada. Pior, para encontrar erros em tarefas, o compilador precisa saber seus intenções e encontrar lugares onde suas intenções diferem do seu código. Isso é muito claramente impossível.

No entanto, isto não significa que nenhuma verificação deve ser feito. Se houver classes de problemas que são fáceis de detectar, então faz sentido para prendê-los.

Eu não sou suficientemente familiarizado com pylint e pychecker para dizer o que classes de erros que eles vão pegar. Como eu disse que eu sou muito inexperiente com python.

Estes programas de análise estática são úteis. No entanto, acredito que a menos que duplicar as capacidades do compilador, o compilador será sempre em uma posição para "saber" mais sobre o programa do que qualquer verificador de estática podia. Parece um desperdício não aproveitar isso para reduzir erros, sempre que possível.

Update 2:

cdleary - Em teoria, eu concordo com você, um analisador estático pode fazer qualquer validação que o compilador pode. E no caso de Python, deve ser suficiente.

No entanto, se o seu compilador é suficiente complexo (especialmente se você tiver lotes de pragmas que a mudança como compilação ocorre, ou se, como Perl, você pode executar um código em tempo de compilação), então o analisador estático deve aproximar-se da complexidade do compilador / intérprete para fazer a análise.

Heh, toda essa conversa de compiladores complexos e código executado em shows tempo de compilação meu Perl fundo.

O meu entendimento é que o Python não tem pragmas e não pode executar código arbitrário em tempo de compilação. Então, a menos que eu estou errado ou esses recursos são adicionados, um analisador relativamente simples no analisador estático deve ser suficiente. Certamenteseria útil para forçar essas verificações em cada execução. Claro, a maneira que eu faria isso é com um pragma.

Depois de adicionar pragmas à mistura, você começou a descer uma ladeira escorregadia e a complexidade do que você analisador deve crescer em proporção com o poder ea flexibilidade que você fornecer em seus pragmas. Se você não for cuidadoso, você pode acabar como Perl, e depois "única python pode analisar Python," um futuro que eu não gostaria de ver.

Talvez uma opção de linha de comando seria a melhor maneira de adicionar análise estática forçado;)

(De modo algum a intenção de impugnar as capacidades do Python quando eu digo que não pode futz com o comportamento tempo de compilação como Perl pode. Eu tenho um palpite de que esta é uma decisão de design cuidadosamente considerado, e eu posso ver a sabedoria .-lo extrema flexibilidade do Perl em tempo de compilação é, IMHO, uma grande força e uma fraqueza terrível da língua;. Eu vejo a sabedoria desta abordagem também)

Python tem algo que pode mudar sintaxe script:

from __future__ import print_function

e vários outros futuros-características que têm implicações de sintaxe. É que a sintaxe do Python tem sido mais rigorosa, mais estável e mais bem definida do que Perl histórica; o tipo de coisas que ‘strict refs’ e ‘subs rigorosas’ proíbem nunca existiu em Python.

‘vars rigorosas’ destina-se principalmente às referências parada typoed e perdeu-out dos meus do de criar globals acidentais (bem, variáveis ??de pacote em termos Perl). Isso não pode acontecer em Python como atribuições nuas padrão a declaração local, e deu à luz símbolos não atribuídos resultar em uma exceção.

(Há ainda o caso em que os usuários acidentalmente tentar write-through para um mundial sem declará-lo com uma declaração 'global', fazendo com que seja uma acidental local ou, mais frequentemente, um UnboundLocalError. Isso tende a ser aprendido rapidamente , mas é um caso discutível onde ter de declarar seus habitantes poderia ajudar. Embora alguns programadores experientes Python aceitará a carga legibilidade.)

Outros linguagem e biblioteca mudanças que não envolvem a sintaxe são tratadas através dos avisos sistema .

Eu acho que há alguma confusão quanto a que "use strict" faz, a partir dos comentários que eu estou vendo. Ele não liga verificações de tipo tempo de compilação (para ser como Java). Nesse sentido, progammers Perl estão de acordo com os programadores python. Como S. Lott diz acima desses tipos de cheques não protegem contra erros de lógica, não reduzir o número de testes de unidade, você precisa escrever e nós também não somos grandes fãs de programação escravidão.

Aqui está uma lista do que "use strict" faz:

  1. Usando referências simbólicas é um erro de tempo de execução. Isso você impede de fazer loucos (mas às vezes úteis coisas como)

    $var = 'foo';

    $foo = 'bar';

    print $$var; # this would contain the contents of $foo unless run under strict

  2. Usando variáveis ??não declaradas é um erro de tempo de execução (isto significa que você precisa usar o "meu", "nosso" ou "local" para declarar âmbito do seu variável antes de usá-lo.

  3. erros de sintaxe em tempo de compilação
  4. Todos os barewords são considerados. Barewords são palavras que não tenham sido declarados como símbolos ou sub-rotinas. Isto é principalmente para proibir algo que foi feito historicamente, mas é considerado como tendo sido um erro.

Python não tem verdadeiro escopo lexical, de modo vars rigorosos não seria muito sensato. Ele não tem referências simbólicas AFAIK, por isso não precisa para strict refs. Não tem barewords, por isso não tem necessidade de vars estritas.

Para ser honesto, é apenas escopo lexical eu sinto falta. Os outros dois eu consideraria verrugas em Perl.

Esta resposta original é correto, mas não, talvez, explicar a situação em um sentido prático.

Existem ferramentas de análise estática para Python, mas verificações de tempo de compilação tendem a ser> diametralmente oposta à de tempo de execução filosofia ligação que abraços Python.

O que usar estrita », dispõe no Perl é a capacidade de garantir que uma mis-espelta ou nome da variável é (geralmente) capturado no tempo de compilação. Isso faz melhorar código confiabilidade, e acelera o desenvolvimento. Mas, a fim de fazer tal coisa uma pena, você precisa declarar variáveis. E estilo Python parece desencorajar isso.

Assim, em Python, você nunca descobrir sobre uma variável mis-espelta até que você observe a run-time que a atribuição você pensou que você fez não está sendo feito, ou que uma expressão parece determinação de um valor inesperado. Pegar esses erros pode ser demorado, principalmente porque os programas obter grande, e como as pessoas são forçadas a manter código desenvolvido por outros.

Java e C / C ++ dar um passo ainda mais, com a verificação de tipo. A motivação é prático, ao invés de filosófico. Como você pode pegar o maior número de erros possível, logo que possível, e ter certeza que você eliminar todos eles antes de liberar o código para produção? Cada linguagem parece ter uma estratégia particular e correr com ele, com base no que eles acho que é importante. Em uma linguagem como Perl, onde a ligação em tempo de execução não é suportado, faz sentido para aproveitar 'use strict' para facilitar o desenvolvimento.

Eu considero o 'use strict' em Perl mais como um pragma como você insinuou: ele muda o comportamento do compilador.

filosofia da linguagem Perl é diferente da filosofia python. Como em, você terá mais do que bastante corda para pendurar-se repetidamente, em Perl.

Larry Wall é grande na lingüística, por isso temos de Perl o que é referido como o TIMTOWTDI (tim-toe-dee digamos) princípio vs. Zen de python:

Não deve haver um-- e de preferência apenas uma maneira --obvious para fazê-lo.

você poderia muito facilmente usar pylint e PyChecker para avançar com o seu próprio sabor de use strict para python (ou algo análogo ao perl -cw *scriptname*), mas por causa das diferentes filosofias na concepção língua, você não vai encontrar isso em prática amplamente.

Com base no seu comentário ao primeiro cartaz, você está familiarizado com import this de python. Há um monte de coisas lá dentro que iluminam por que você não vê um equivalente de use strict em Python. Se você meditar sobre o koan encontrada no Zen de Python, você pode encontrar a iluminação para si mesmo. :)

Eu achei que eu só realmente se preocupam com a detecção de referências a vars não declarados. Eclipse tem integração pylint via PyDev e, embora pylint está longe de ser perfeito, ele faz um trabalho razoável para isso.

Ele faz o tipo de movimento contra a natureza dinâmica do Python, e eu tenho que adicionar #IGNOREs ocasionalmente, quando o meu código obtém inteligente sobre algo. Mas acho que isso acontece raramente suficiente para que eu estou feliz com isso.

Mas eu podia ver a utilidade de alguns pylint-como funcionalidade tornando-se disponível sob a forma de uma bandeira de linha de comando. Tipo como Python 2.6 de -3 interruptor, que identifica pontos de incompatibilidade entre Python 2.xe 3.x código.

É muito difícil escrever grandes programas sem 'use strict' em Perl. Sem 'use strict', se você usar uma variável de novo, e cometer erros de ortografia-lo, deixando uma carta para fora, o programa ainda funciona. E sem casos de teste para verificar os seus resultados, você nunca pode encontrar tais erros. Pode ser muito para encontrar porque você está obtendo resultados errados devido a esse motivo demorado.

Alguns dos meus programas Perl consistem em 5.000 linhas para 10.000 linhas de código divididos em dezenas de módulos. Não se pode realmente fazer a programação de produção sem 'use strict'. Eu nunca iria permitir que o código de produção para ser instalado na fábrica com línguas que não aplicam "declarações de variáveis".

É por isso que Perl 5.12.x agora tem o 'use strict', como o comportamento padrão. Você pode desligá-los.

PHP me deu alguns problemas por causa da não aplicação da declaração da variável. Então, você precisa limitar-se a pequenos programas com este idioma.

Apenas uma opinião ...

abcParsing

Perl é uma língua desenfreada como disseram :). Então você pode usar a variável antes anunciado; Por exemplo: Se você usar um nome var "is_array", mas digite "is_arrby", o compilador não irá relatar erro sem "use strict". Então, quando a codificação programa longo em perl, melhor aproveitamento "use strict" declaração. É claro que, a menos de 50 linhas para a execução de um script de tempo, não há necessidade :)

Parece que o ideal de "Pythonic" código serve um monte da mesma finalidade que use strict.

Eu não tenho um fundo Perl, mas pelo que eu sei, não há nenhum recurso em python que precisa ser desativado para que seu código para ser "mais confiável", então, nesse sentido, eu acho que você pode dizer é desnecessário

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top