Como você faria o equivalente a directivas de pré-processamento em Python?
-
20-08-2019 - |
Pergunta
Existe uma maneira de fazer as seguintes diretivas de pré-processamento em Python?
#if DEBUG
< do some code >
#else
< do some other code >
#endif
Solução
está lá __debug__
, que é um valor especial que o compilador faz preprocess.
if __debug__:
print "If this prints, you're not running python -O."
else:
print "If this prints, you are running python -O!"
__debug__
será substituído por uma constante 0 ou 1 pelo compilador, e o otimizador irá remover quaisquer linhas if 0:
antes de sua fonte é interpretado.
Outras dicas
Eu escrevi um pré-processador python chamado pypreprocessor que faz exatamente o que você está descrevendo.
A fonte e documentação está disponível no GitHub .
O pacote também podem ser baixados / instalados através do PyPI .
Aqui está um exemplo para realizar o que você está descrevendo.
from pypreprocessor import pypreprocessor
pypreprocessor.parse()
#define debug
#ifdef debug
print('The source is in debug mode')
#else
print('The source is not in debug mode')
#endif
pypreprocessor é capaz de muito mais do que apenas on-the-fly pré-processamento. Para ver exemplos de casos mais uso verificar o projeto no Google Code.
Update: Mais informações sobre pypreprocessor
A forma como eu realizar a pré-processamento é simples. A partir do exemplo acima, as importações de pré-processamento de um objeto pypreprocessor que é criado no módulo pypreprocessor. Quando você chama parse () sobre o pré-processador auto-consome o arquivo que ele é importado para e gera uma cópia temporária de si mesmo que os comentários fora todo o código pré-processador (para evitar o pré-processador de chamar a si mesma recursivamente em um loop infinito) e comentários fora de todas as partes não utilizadas.
comentar as linhas é, em oposição a removê-los, é necessário para preservar os números de linha no tracebacks de erro se o módulo inicia uma excepção ou falhas. E eu tenho mesmo ido tão longe como para reescrever o rastreamento de erro de relatório refletem o nome do arquivo apropriado do módulo que caiu.
Em seguida, o arquivo gerado contendo o código de pós-processado é executado on-the-fly.
A vantagem de usar este método sobre apenas adicionando um monte de if in-line no código é, não haverá tempo de execução desperdiçado avaliar declarações inúteis, pois as porções comentadas do código será excluído dos arquivos .pyc compilados .
A desvantagem (e minha razão original para criar o módulo) é que você não pode executar tanto python 2x e 3x python no mesmo arquivo porque pítons intérprete executa uma verificação de sintaxe completa antes de executar o código e rejeitará qualquer versão específica código antes do pré-processador tem permissão para executar :: suspiro ::. Meu objetivo inicial era ser capaz de desenvolver 2x e 3x código lado-a-lado no mesmo arquivo que criaria versão específica bytecode dependendo do que está sendo executado.
De qualquer forma, o módulo de pré-processamento ainda é muito útil para a implementação de capacidades de pré-processamento comum de estilo c. Bem como, o pré-processador é capaz de emitir o código de pós-processado para um arquivo para uso posterior, se quiser.
Além disso, se você deseja gerar uma versão que tem todas as directivas de pré-processamento, bem como qualquer um dos #ifdefs que são excluídos removidos é tão simples quanto definindo um sinalizador no código de pré-processamento antes de chamar parse (). Isso faz com que a remoção de código indesejado a partir de um arquivo de origem específica versão um processo de uma etapa (vs rastreamento através do código e remove se declarações manualmente).
Eu suspeito que você vai odiar esta resposta. A maneira de fazer isso em Python é
# code here
if DEBUG:
#debugging code goes here
else:
# other code here.
Uma vez que python é um intérprete, não há nenhuma etapa de pré-processamento a ser aplicada, e nenhuma vantagem especial para ter uma sintaxe especial.
Você pode usar o pré-processador em Python. Basta executar seus scripts através do CPP (C-Preprocessor) em seu diretório bin. No entanto, eu fiz isso com Lua e os benefícios de fácil interpretação ter ultrapassado o IMHO compilação mais complexa.
Você pode apenas usar as construções de linguagem normal:
DEBUG = True
if DEBUG:
# Define a function, a class or do some crazy stuff
def f():
return 23
else:
def f():
return 42
Um método alternativo é usar um script para comentar porções de código que só são relevantes para a depuração. Abaixo está um script de exemplo que comenta as linhas que têm uma declaração '#Depurar' nele. Ele também pode remover esses marcadores de comentários novamente.
if [ "$1" == "off" ]; then
sed -e '/^#/! {/#DEBUG/ s/^/#/}' -i *.py
echo "Debug mode to $1"
elif [ "$1" == "on" ]; then
sed -e '/#DEBUG/ s/^#//' -i *.py
echo "Debug mode to $1"
else
echo "usage: $0 on | off"
fi
- Python se não pode eliminar elementos de arrays.
- pré-compiladores C não lidar com #! ou outras linhas que começam com # conforme necessário.
- pypreprocessor parece ser python específica
Use um m4 comum em vez disso, como este:
ifelse(DEBUG,True,dnl`
< do some code >
dnl,dnl`
< do some other code >dnl
')
ifelse(
M4_CPU,x86_64,`
< do some code specific for M4_CPU >
',M4_CPU,arm,`
< do some code specific for M4_CPU >
',M4_CPU,ppc64le,`
< do some code specific for M4_CPU >
')
ifelse(
M4_OS,windows,`
< do some code specific for M4_OS >
',M4_OS,linux,`
< do some code specific for M4_OS >
',M4_OS,android,`
< do some code specific for M4_OS >
')
m4 -D DEBUG = True -D M4_OS = android -D M4_CPU = armar test.py.m4> test.py