Devo realmente usar todas as maiúsculas para minhas constantes?


34

Eu sou um programador Python principalmente que usa o pylint para aprender código-fonte. Consigo eliminar todos os avisos, exceto um: Nome inválido para uma constante. Mudar o nome para todas as letras maiúsculas corrige isso, mas devo mesmo fazer isso? Se eu fizer isso, acho que meu código parece feio, pois a maioria das variáveis ​​é constante (de acordo com pylint).


2
Se a maioria das suas variáveis ​​são constantes no nível do módulo, você provavelmente está fazendo algo incomum. A maioria deles deve viver dentro de funções.
RemcoGerlich 16/02

1
você pode nos mostrar uma amostra do seu código que a Pylint acha que são constantes?
Winston Ewert

@WinstonEwertNOTES_DIRECTORY = argv[1] chdir(NOTES_DIRECTORY) FILES = glob('*.txt') RAND_FILE = choice(FILES) with open(RAND_FILE) as notes_file: POINTS = notes_file.readlines() RAND_POINT = choice(POINTS)
Abhishek Kumar

@AbhishekKumar, seu código está em uma função ou está no nível superior?
Winston Ewert

@WinstonEwert No nível superior e depois de seguir as instruções do PyLint.
Abhishek Kumar

Respostas:


33

Você provavelmente está escrevendo um código como este:

notes_director = argv[1]
chdir(notes_director)
files = glob('*.txt')
rand_file = choice(files)
with open(rand_file) as notes_file: 
    points = notes_file.readlines() 
    rand_point = choice(points)

Você deve mover esse código para uma função:

def main():
    notes_director = argv[1]
    chdir(notes_director)
    files = glob('*.txt')
    rand_file = choice(files)
    with open(rand_file) as notes_file: 
        points = notes_file.readlines() 
        rand_point = choice(points)

# actually call the main function    
main()

Pylint assume que o código que realmente faz o trabalho estará dentro de uma função. Como você tem esse código no nível superior do seu código, em vez de dentro de uma função, ele fica confuso.

De um modo geral, é melhor estilo trabalhar dentro de uma função do que no nível superior. Isso permite que você organize melhor o que está fazendo e facilita a reutilização. Você realmente deve ter apenas código executando um algoritmo fora de uma função em um script rápido e sujo.


1
Discordo totalmente, acho que existem muitas boas razões pitônicas para usar variáveis ​​no nível do módulo. Penso que este conselho é apenas um artefato de leitura incorreta do PEP8, e assumir que o inverso de "constantes deve estar no nível do módulo" também deve ser verdadeiro.
MetricSystem

21

Sim. De acordo com a regra do PEP8s sobre constantes :

As constantes são geralmente definidas no nível do módulo e escritas em letras maiúsculas com sublinhados que separam as palavras. Exemplos incluem MAX_OVERFLOWe TOTAL.

Versão longa:

Na comunidade Python (como em muitas outras comunidades) existem convenções sobre como escrever código. Isso é diferente do código de trabalho : mesmo se você escrever todas as suas constantes em minúsculas, seu código ainda funcionará.

Mas existe um consenso da comunidade (conforme documentado no PEP8) que é "imposto" com ferramentas como o pylint . Se você programa para a sua própria felicidade, pode negligenciar as dicas que o pilão dá. Se você deseja um intercâmbio aberto com a comunidade, também conhecido como »alguém além de mim deve usar meu código«, você deve preparar seu código de acordo com o PEP8.


7
Por outro lado, é perfeitamente possível pylinterrar. O Python não fornece uma maneira de distinguir uma constante de uma variável, exceto que a constante deve sempre ter o mesmo valor. pylintassume que tudo o que é definido apenas uma vez e nunca muda é uma constante, mas, a menos que se pretenda que seja uma constante, isso poderia ser apenas um artefato da implementação. E, especificamente, o código fornecido no comentário da pergunta possui valores que serão diferentes a cada execução, portanto, não devem ser considerados constantes, mesmo que o pylint pense que são.
Jules

@Jules Eu chamaria variáveis ​​definidas uma vez e as alterações durante o tempo de execução nunca mais uma constante, portanto, existe em muitas línguas (por exemplo, em JS) uma constpalavra - chave. Embora o valor inicial seja diferente, exceto talvez PI.
Thomas Junk

1
Eu distinguiria entre uma variável imutável (ou seja, algo definido em tempo de execução e que não foi alterado) e uma constante (ou seja, algo que é o mesmo em cada execução de programa, e se a linguagem fornecer a opção para fazê-lo, ela poderá ser computada em tempo de compilação ) ... o ponto é que, como não existe uma maneira de especificar a distinção entre python, pylintassume o último mesmo quando o primeiro é o caso.
Jules

Pylint está definitivamente errado, na medida em que lê "constantes devem estar no nível do módulo" e assumiu que o inverso "nível do módulo deve ser constante". Mas, por ser uma ferramenta boa e útil, parece que estamos ficando presos a ela.
MetricSystem

@MetricSystem, que função, na sua opinião, uma variável de nível de módulo teria além de ser uma constante? Deveria ser mutável?
Thomas Junk

13

A norma da comunidade PEP8 e Python é usar ALL_CAPS_CONSTANTS. É uma pista visual comum, usada há décadas em C, Java, Perl, PHP, Python, bash e outras linguagens de programação e ambientes de shell. Mas no jargão online moderno, TODOS OS TAMPAS SIGNIFICA GRITOS . E gritar é rude.

Python é, no entanto, bastante inconsistente ALL_CAPS_CONSTANTS. JavaScript pode ter Math.PI, mas Python tem math.pi. Não há constante mais reconhecível ou duradoura que π. Ou considere sys.version_info, a versão do Python em que você está executando. 100% constante durante a vida do seu programa - muito mais do que PORTou MAX_ITERATIONSou outras constantes que você definir. Ou que tal sys.maxsize? O valor inteiro nativo máximo da sua plataforma é constante ao longo de não apenas uma ou duas execuções do programa, mas também da vida útil do seu hardware.

Se estas constantes - incluindo alguns como π e e que são constantes fundamentais do universo, e não vai variar ao longo do toda a eternidade - se eles podem estar em letras minúsculas, bem ... assim pode outras constantes. Você pode escolher.

Lembre-se, o PEP8 é um guia de estilo. Uma diretriz, não uma lei. Uma diretriz frequentemente violada mesmo pela biblioteca padrão do Python. E citando outra diretriz básica do Python, PEP20 (também conhecida como "O Zen do Python"):

  • Bonito é melhor que feio
  • A legibilidade conta
  • A praticidade supera a pureza.

Em uma nota prática, quando um programa começa YELLY_CONSTANTe SHOUTY_PARAMETERcomeça a ralar, ajuda a lembrar que as constantes all-caps geralmente não são realmente ideais platônicos duradouros , mas parâmetros de um programa executado. Não há nada verdadeiramente constante sobre PORT, SITENAMEou NUMRUNS, e eles não têm de ser geridos como globais programa independente. Por exemplo, eles podem ser inseridos em um dicionário como um pacote globalmente acessível de parâmetros de programa:

config = {
    'port': 80,
    'sitename': "Bubba's Blog",
    'numruns': 100,
}

O Python também possui um bom recurso de passagem de parâmetros de palavras-chave que reduz a necessidade de usar APPARENTLY_ANGRY_GLOBAL_VARIABLES:

def process_data(sitename, port=80, numruns=100):
    ...

process_data("Bubba's Blog")

Na prática, muitos desses valores serão (ou deveriam ser) lidos em arquivos de configuração, variáveis ​​de ambiente do SO, argumentos de linha de comando ou outras fontes para satisfazer a inversão do princípio / padrão de controle . Mas essa é uma história maior para outro dia.


1

Sim, é bastante comum na maioria das linguagens de programação (pelo menos nas que eu uso).

Você pode consultar este link do Google para compartilhar um estilo comum entre desenvolvedores da mesma equipe.

É aconselhável usar

Type                  |Public          |Internal
Global/Class Constants|CAPS_WITH_UNDER |_CAPS_WITH_UNDER
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.