Mais

Usando bloco de código de função definido com Python no ArcGIS

Usando bloco de código de função definido com Python no ArcGIS


Estou executando um cálculo de campo em um script Python no ArcGIS. Dentro deste cálculo de campo, estou chamando uma função definida dentro de um bloco de código.

Aqui está o diálogo que executei e funciona:

Isso funcionou. No entanto, não consigo traduzir isso em meu código Python:

Aqui está o código:

#Calculate YSLB expression = "output (! MTH_BRNT!,! YR_BRNT!,! YSLB!)" Code_block = "def output (MTH_BRNT, YR_BRNT, YSLB): / n mês = str (month_val) / n month_current = int (mês) / n month_fire = int (MTH_BRNT) / n ano = str (high_year) / n year_current = int (year) / n year_fire = int (YR_BRNT) / n Mc = (12 * (year_current-1)) + month_current / n Mf = (12 * (year_fire-1)) + month_fire / n return (Mc-Mf) / 12 "arcpy.CalculateField_management (fuel_age_out," YSLB ", expression," PYTHON_9.3 ", code_block)

Já conheci esse problema antes. Tente usar "" "em vez de" acima da expressão.

Caso contrário, tente este:

code_block = "" "def output (MTH_BRNT, YR_BRNT, YSLB): mês = str (month_val) month_current = int (month) / n month_fire = int (MTH_BRNT) year = str (high_year) / n year_current = int (year) year_fire = int (YR_BRNT) Mc = (12 * (ano_atual-1)) + mês_atual Mf = (12 * (ano_fogo-1)) + mês_fogo retorno (Mc-Mf) / 12 "" "

às vezes o python não reconhece o n


No Python, um bloco é um recurso sintático (um recuo sob as instruções de abertura do bloco como if ou def) e não um objeto. O recurso que você espera pode ser um fechamento (que pode acessar variáveis ​​fora do bloco), que você pode obter usando funções internas, mas qualquer chamável pode ser usado. Por causa de como lambda funciona em Python, a definição de função embutida que você mostrou com do | arg | é limitado a uma única expressão.

Aqui está uma reescrita grosseira de seu código de amostra em Python.

Uma variante usa um loop for para deixar claro que o loop é finito:

Freqüentemente, ao passar chamáveis ​​como este, você já terá a função que deseja disponível em algum lugar e não precisará redefini-la. Por exemplo, métodos em objetos (métodos vinculados) são chamáveis ​​perfeitamente válidos.


Métodos

Marca o parâmetro como tendo um erro (um X vermelho) com a mensagem fornecida. As ferramentas não são executadas se algum dos parâmetros apresentar um erro.

Marca o parâmetro como tendo um aviso (um triângulo amarelo) com a mensagem fornecida. Ao contrário dos erros, as ferramentas são executadas com mensagens de aviso.

setIDMessage (messageType: string, messageID: string, , )

Permite que você defina uma mensagem do sistema. Os argumentos são iguais aos da função AddIDMessage.

Limpa qualquer texto de mensagem e define o status como informativo (sem erro ou aviso).

Retorna verdadeiro se o parâmetro contém um erro.

Retorna verdadeiro se o parâmetro contém um aviso.

Retorna verdadeiro se a ferramenta está sendo validada dentro de um modelo e o valor de entrada é a saída de outra ferramenta no modelo.

Propriedades

Direção de entrada / saída do parâmetro.

String: "Obrigatório", "Opcional", "Derivado"

Uma lista de índices de cada parâmetro dependente.

O valor do parâmetro.

False se o parâmetro não estiver disponível.

Verdadeiro se o usuário modificou o valor.

Verdadeiro se a rotina de validação interna tiver verificado o parâmetro.

A categoria do parâmetro.

O esquema do conjunto de dados de saída.

O filtro a ser aplicado aos valores no parâmetro.

O caminho para um arquivo de camada (.lyr) usado para desenhar a saída.

A mensagem a ser exibida ao usuário. Consulte SetErrorMessage e SetWarningMessage acima.

ParâmetroDependências

Normalmente, você define dependências de parâmetro para uso pelo objeto Schema. Existem dois casos em que as dependências já podem estar definidas no método getParameterInfo da ferramenta.

  • Para um parâmetro de conjunto de dados de saída cujo tipo é Derivado, a dependência é o índice do parâmetro do qual derivar a saída.
  • Para certos tipos de dados de entrada, a dependência é o índice do parâmetro que contém as informações usadas pelo controle, conforme mostrado na tabela abaixo.

A tabela que contém os campos.

Item INFO ou Expressão INFO

A tabela INFO contendo os itens.

A cobertura contendo recursos.

Unidades de área ou unidades lineares

Um conjunto de dados geográficos usado para determinar as unidades padrão.

Um espaço de trabalho usado para determinar o sistema de coordenadas padrão.

Configurações de hierarquia do analista de rede

O conjunto de dados da rede contendo informações de hierarquia.

Tabela de valores geoestatísticos

A camada de análise contendo tabelas.

parameterDependencies é equivalente à configuração Obtained From do assistente da Ferramenta de Script.

As dependências são normalmente definidas no método getParameterInfo:

Valor

Este é o valor do parâmetro que o usuário inseriu ou que você definiu programaticamente. Você pode definir o valor no método getParameterInfo, caso em que ele serve como o valor padrão inicial para o parâmetro. Você também pode definir o valor em updateParameters em resposta à entrada do usuário, conforme mostrado abaixo.

A propriedade de valor de um parâmetro retorna um objeto, a menos que o parâmetro não seja preenchido, caso em que o valor retorna Nenhum. Para se proteger contra o não preenchimento de um parâmetro, use uma verificação if antes de usar seu valor.

O trecho de código abaixo testa se o valor é igual à string "Get Spatial Weights From File". Este teste funciona porque o tipo de dado do parâmetro é uma string.

Como um objeto Value não suporta a manipulação de string, use a propriedade value do objeto Value sempre que uma string for manipulada ou analisada. O exemplo de código usa o método os.path.dirname para retornar o diretório de um conjunto de dados.

Com exceção de Describe, não use métodos que usam um caminho de catálogo, como ListFields, na validação. O conjunto de dados pode não existir quando sua ferramenta é validada no ModelBuilder e o método pode falhar ou fornecer resultados inesperados.

No caso específico de ListFields, a propriedade fields do objeto Describe fornecerá as informações equivalentes.

Não defina um valor de parâmetro em updateMessages (), pois o valor não será validado pela rotina de validação interna.

Alterado

altered é verdadeiro se o usuário alterou o valor de um parâmetro - inserindo um caminho de saída, por exemplo. Uma vez alterado um parâmetro, ele permanece alterado até que o usuário esvazie (apague) o valor, caso em que volta a ser inalterado. Alterar programaticamente um valor com código de validação não altera o estado alterado. Ou seja, se você definir um valor para um parâmetro, o estado alterado do parâmetro não muda.

altered é usado para determinar se você pode alterar o valor de um parâmetro. Por exemplo, suponha que uma ferramenta tenha um parâmetro de classe de recurso e um parâmetro de palavra-chave. Se a classe de recurso contém pontos ou polígonos, as palavras-chave são RED, GREEN e BLUE, e se as linhas, ORANGE, YELLOW, PURPLE e WHITE.

Suponha que o usuário insira uma classe de recurso de ponto. Se o parâmetro da palavra-chave estiver inalterado, você define o valor como VERMELHO, uma vez que é o valor padrão.

Se uma classe de recurso de linha for inserida, você definirá o valor padrão para LARANJA, desde que o parâmetro de palavra-chave permaneça inalterado.

No entanto, se o parâmetro de palavra-chave foi alterado pelo usuário (ou seja, a palavra-chave está definida como VERDE), você não deve redefinir a palavra-chave - o usuário fez sua escolha (VERDE) e você não sabe sua intenção - ele podem alterar a classe de recurso para que VERDE seja válido ou eles podem alterar a palavra-chave (para ROXO, por exemplo). Como GREEN não é membro do conjunto de palavras-chave que você criou para as linhas, a validação interna sinaliza o parâmetro como um erro. O usuário tem duas opções neste ponto - alterar a classe do recurso de entrada ou alterar a palavra-chave.

HasBeenValidated

hasBeenValidated é false se o valor de um parâmetro foi modificado pelo usuário desde a última vez que updateParameters e internal validate foram chamados. Depois que a validação interna é chamada, o geoprocessamento define automaticamente hasBeenValidated como verdadeiro para todos os parâmetros.

hasBeenValidated é usado para determinar se o usuário alterou um valor desde a última chamada para updateParameters. Você pode usar essas informações para decidir se deve fazer sua própria verificação do parâmetro.


Fluxo de controle em Python

Uma das características mais distintas do Python é o uso de indentação para marcar blocos de código. Considere a instrução if de nosso programa simples de verificação de senha:

As linhas imprimir ('Fazendo logon.') e imprimir ('Senha incorreta.') são dois separados blocos de código. Acontece que esses têm apenas uma única linha, mas o Python permite escrever blocos de código que consistem em qualquer número de instruções.

Para indicar um bloco de código em Python, você deve recuar cada linha do bloco na mesma quantidade. Os dois blocos de código em nosso exemplo de instrução if são ambos recuados com quatro espaços, que é uma quantidade típica de recuo para Python.

Na maioria das outras linguagens de programação, o recuo é usado apenas para ajudar a tornar o código mais bonito. Mas em Python, é necessário para indicar a qual bloco de código uma instrução pertence. Por exemplo, o final imprimir ('Tudo pronto!') é não recuado, e assim é não parte do bloco else.

Programadores familiarizados com outras linguagens geralmente se arrepiam com a ideia de que o recuo é importante: muitos programadores gostam da liberdade de formatar seu código como quiserem. No entanto, as regras de recuo do Python são bastante simples, e a maioria dos programadores já usa o recuo para tornar seu código legível. Python simplesmente leva essa ideia um passo adiante e dá significado ao recuo.

  • O IDLE foi projetado para recuar o código automaticamente para você. Por exemplo, pressionando Return depois de digitar o : em um if-header recua automaticamente o cursor na próxima linha.
  • A quantidade de indentação é importante: um espaço ausente ou extra em um bloco Python pode causar um erro ou comportamento inesperado. As instruções dentro do mesmo bloco de código precisam ser indentadas no mesmo nível.

Declarações if / elif

Uma instrução if / elif é uma instrução if generalizada com mais de uma condição. É usado para tomar decisões complexas. Por exemplo, suponha que uma companhia aérea tenha as seguintes taxas de passagens & # 8220child & # 8221: crianças de 2 anos ou menos voam de graça, crianças maiores de 2 anos, mas menores de 13 anos, pagam tarifa infantil com desconto e qualquer pessoa com 13 anos ou mais paga uma tarifa normal tarifa de adulto. O programa a seguir determina quanto um passageiro deve pagar:

Depois que Python obtém idade do usuário, ele insere a instrução if / elif e verifica cada condição uma após a outra na ordem em que são fornecidas. Então, primeiro ele verifica se idade é menor que 2 e, se for o caso, indica que o vôo está livre e salta da condição de elif. Se idade não é menor que 2, então ele verifica a próxima condição elif para ver se idade está entre 2 e 13. Em caso afirmativo, ele imprime a mensagem apropriada e salta para fora da instrução if / elif. Se nem a condição if nem a condição elif forem Verdadeiro, então ele executa o código no bloco else.

  • elif é curto para mais se, e você pode usar quantos blocos elif forem necessários.
  • Como de costume, cada um dos blocos de código em uma instrução if / elif deve ser consistentemente indentado com a mesma quantidade. O Python não apenas requer esse recuo para que possa reconhecer os blocos de código, mas o recuo consistente torna mais fácil para as pessoas reconhecerem as condições if / elif e seus blocos de código correspondentes.
  • Tal como acontece com uma instrução if regular, o bloco else é opcional. Em uma instrução if / elif com um outro bloco, exatamente um dos blocos if / elif serão executados. Se não houver bloco else, é possível que nenhuma das condições seja Verdadeiro, caso em que nenhum dos blocos if / elif é executado.
  • Uma instrução if / elif deve ter exatamente um bloco if, zero ou mais blocos elif e zero ou um bloco else.

Expressões condicionais

Python tem mais um operador lógico que alguns programadores gostam (e outros não!). É essencialmente uma notação abreviada para instruções if que podem ser usadas diretamente nas expressões. Considere este código:

A expressão do lado direito de = na segunda linha é chamado de expressão condicional, e avalia para qualquer 'que nojo' ou 'yum'. É equivalente ao seguinte:

Expressões condicionais geralmente são mais curtas do que as instruções if / else correspondentes, embora não sejam tão flexíveis ou fáceis de ler. Em geral, você deve usá-los para tornar seu código mais simples.


7 respostas 7

É difícil ver em sua postagem qual é o problema, mas um if-else está formatado dessa forma

Ou seja, o outro precisa estar no mesmo nível como o correspondente se.

Às vezes, quando seu editor faz o recuo automático para você e você também edita manualmente, as coisas podem ficar confusas, então você terá que descobrir como seu editor lida com indentações (por exemplo, ele está sempre usando tabulações ou espaços ?, o que acontece se você clicar em retornar etc).

Além disso, desconfie de misturar tabulações e espaços, isso também causará problemas (difícil de detectar, pois ambos são & quotinvisíveis & quot)

O else deve estar no mesmo nível de recuo que o if com o qual está acoplado:

Mesmo se o seu editor estiver recuando automaticamente para você, você ainda deve desfazer o recuo para tornar o código sintaticamente correto.

Conseguir o recuo correto não é realmente um problema do Python, mas sim um problema com o editor que você está usando para o seu código-fonte.

A maioria dos editores que entendem Python adicionará corretamente um nível de indentação após dois pontos (como você está vendo). Como você pode ter quantas instruções quiser nesse bloco de código, o editor não tem como saber quando & quotoutdent & quotar a próxima linha para o else.

Você tem que dizer ao editor para ultrapassar essa linha pressionando backspace ou Shift + Tab na linha antes de começar a digitar.

Se você estiver inserindo a parte else depois que o resto do código for escrito, certifique-se de que os caracteres que você usa para indentar são os mesmos da instrução if. Se a instrução if estiver indentada com espaços, use o mesmo número de espaços para else. Se a instrução if estiver recuada com uma ou mais guias, use o mesmo número de guias para a instrução else. Não misture espaços e tabulações para indentação.

Não presuma que só porque as linhas & quotparecem & quot como se estivessem indentadas da mesma forma que está recuado o mesmo. Um pode usar espaços e outro pode usar tabulações (ou alguma combinação).


3 respostas 3

Listas negras simples são a pior maneira de corrigir uma vulnerabilidade. Eles criarão muitos falsos positivos e qualquer invasor determinado geralmente encontrará uma maneira de contorná-los.

Os firewalls de aplicativos da Web são um bom exemplo. As regras de detecção que eles empregam são muito mais complicadas do que sua lista negra simplista, mas não captam tudo e, de vez em quando, surgem desvios para coisas que eles está deveria pegar.

Não vejo nenhuma possibilidade de escapar disso.

Ou então você pensa. Você simplesmente não olhou o suficiente.

Isso passa direto pelo seu filtro. Ele chama a função exec () que então passa a imprimir 'pwned'.

Agora você pode modificar sua lista negra para detectar isso também, mas outra pessoa surgirá de outra maneira.

99% das vezes que vejo alguém usando algo como exec ou eval, é completamente desnecessário. Se você pode evitar o uso de exec, faça um favor a si mesmo e livre-se dessa vulnerabilidade que está esperando para ser explorada. Se, no entanto, você absolutamente precisar para usar exec, então faça como @amon sugerido nos comentários: Crie um novo pipe, bifurque e elimine tantos privilégios no filho quanto possível e, em seguida, execute o código. Use o tubo para se comunicar entre os processos filho e pai. Ou faça uma sandbox como sugeriu Steffen Ullrich.


7 Exemplos de função Python com parâmetros, retorno e tipos de dados

Funções são fragmentos de código em um bloco que recebe um nome. Ele recebe a entrada, executa cálculos ou uma ação e retorna a saída.

Funções aumentam a capacidade de reutilização do código.

Neste tutorial, discutiremos os seguintes exemplos:

  1. Exemplo de função Python básica
  2. Funções integradas do Python
  3. Funções definidas pelo usuário do Python
  4. Parâmetros de função Python
  5. Número desconhecido da função Python de parâmetros
  6. Valor de retorno da função Python
  7. Tipo de dados para parâmetros e valor de retorno

1. Exemplo de função Python básica

A seguir está um exemplo de função Python que usa dois parâmetros e calcula a soma e retorna o valor calculado.

Existem duas categorias amplas de funções em Python: funções embutidas e funções definidas pelo usuário.

2. Funções integradas do Python

Existem muitas funções que vêm junto com o Python, quando ele é instalado. O usuário não precisa se preocupar com as definições das funções. print () é uma das funções embutidas mais comumente usadas em Python.

Mais alguns exemplos de tais funções são: len (), str (), int (), abs (), sum (), etc.

Todas as funções integradas suportadas pelo Python3 estão aqui.

3. Funções definidas pelo usuário do Python

As funções definidas pelo usuário são declaradas usando a palavra-chave def. A palavra-chave deve ser seguida pelo nome da função.

Nessa função, o valor final é calculado aplicando-se juros simples ao principal. calcule_si_amount é o nome da função. principal, taxa e tempo são os parâmetros e a função está retornando os dados calculados.

Não é necessário que uma função aceite parâmetros e retorne valores. Ele pode fazer os dois, ou um deles, ou nenhum. Abaixo está um exemplo de uma função que não aceita nenhum parâmetro, mas retorna dados.

4. Parâmetros da função Python

Uma função pode ter parâmetros padrão.

Nesta função, se o usuário não fornecer o segundo parâmetro b, ele assume que é 10, mas é necessário fornecer o primeiro parâmetro.

5. Número desconhecido da função Python de parâmetros

NOTA: Se houver, digamos, 4 parâmetros em uma função e um valor padrão for definido para o 2º, então o 3º e o 4º parâmetro também devem receber um valor padrão.

Se o número de parâmetros que uma função deve esperar for desconhecido, * args será adicionado à definição da função como um dos parâmetros. Este parâmetro espera uma tupla. O asterisco (*) é importante aqui. O nome args é apenas uma convenção. Pode receber qualquer outro nome.

Da mesma forma, ** kwargs espera um dicionário como parâmetro.

O trecho de código acima faz referência a loop for. Consulte isto para obter mais detalhes: 12 Python essenciais para exemplos de comandos de loop

6. Valor de retorno da função Python

Python permite que a função retorne vários valores.

Aqui, dois valores estão sendo retornados. Quando esta função é chamada, os valores de retorno são armazenados em duas variáveis, simultaneamente.

NOTA: Se uma função não retornar nada, ela implicitamente retornará Nenhum.

7. Tipo de dados para parâmetros e valor de retorno

Definir tipos de dados para parâmetros de função e o valor de retorno pode ser usado para informar ao usuário as expectativas das funções.

A definição da função indica que ela precisa de um parâmetro do tipo int e retornará dois valores do tipo int e list, respectivamente.


Uso de recursos¶

Essas funções são usadas para recuperar informações de uso de recursos:

Esta função retorna um objeto que descreve os recursos consumidos pelo processo atual ou seus filhos, conforme especificado pelo quem parâmetro. O quem O parâmetro deve ser especificado usando uma das constantes RUSAGE_ * descritas abaixo.

Cada um dos campos do valor de retorno descreve como um determinado recurso do sistema foi usado, por exemplo, quantidade de tempo gasto em execução no modo de usuário ou número de vezes que o processo foi trocado da memória principal. Alguns valores dependem do tique do relógio interno, por exemplo, a quantidade de memória que o processo está usando.

Para compatibilidade com versões anteriores, o valor de retorno também é acessível como uma tupla de 16 elementos.

Os campos ru_utime e ru_stime do valor de retorno são valores de ponto flutuante que representam a quantidade de tempo gasto na execução no modo do usuário e a quantidade de tempo gasto na execução no modo do sistema, respectivamente. Os valores restantes são inteiros. Consulte o getrusage (2) página man para obter informações detalhadas sobre esses valores. Um breve resumo é apresentado aqui:


Usando bloco de código de função definido com Python em ArcGIS - Sistemas de Informação Geográfica

Preparando-se para a tecnologia entrevistas?

Aprenda com os melhores
instrutores de campo.


Esta página irá guiá-lo sobre como decifrar qualquer entrevista de programação Python, incluindo:

1. Perguntas da entrevista do mundo real em Python feitas em empresas como Microsoft, Google, Amazon e como respondê-las (economizando seu tempo de preparação para a entrevista).

2. Problemas práticos de Python que você pode resolver imediatamente.

1. O que é Python?

Python é uma linguagem de programação de alto nível, interpretada e de uso geral. Por ser uma linguagem de propósito geral, ela pode ser usada para construir quase qualquer tipo de aplicativo com as ferramentas / bibliotecas certas. Além disso, o python oferece suporte a objetos, módulos, threads, tratamento de exceções e gerenciamento automático de memória que ajudam na modelagem de problemas do mundo real e na construção de aplicativos para resolver esses problemas.

2. Quais são os benefícios de usar Python?

Python é uma linguagem de programação de propósito geral que possui sintaxe simples e fácil de aprender que enfatiza a legibilidade e, portanto, reduz o custo de manutenção do programa. Além disso, a linguagem é capaz de fazer scripts, totalmente de código aberto e oferece suporte a pacotes de terceiros, incentivando a modularidade e a reutilização de código.
Suas estruturas de dados de alto nível, combinadas com tipagem dinâmica e vinculação dinâmica, atraem uma enorme comunidade de desenvolvedores para desenvolvimento e implantação de aplicativos rápidos.

3. O que é uma linguagem tipada dinamicamente?

Antes de entendermos o que é uma linguagem tipada dinamicamente, devemos aprender sobre o que é digitação. Digitando refere-se à verificação de tipo em linguagens de programação. Em um fortemente tipado linguagem, como Python, "1" + 2 resultará em um erro de tipo, uma vez que esses idiomas não permitem "tipo-coerção" (conversão implícita de tipos de dados). Por outro lado, um mal digitado linguagem, como Javascript, simplesmente produzirá "12" como resultado.

  • Estático - Os tipos de dados são verificados antes da execução.
  • Dinâmico - Os tipos de dados são verificados durante a execução.

4. O que é uma linguagem interpretada?

Um Interpretado a linguagem executa suas instruções linha por linha. Linguagens como Python, Javascript, R, PHP e Ruby são exemplos importantes de linguagens interpretadas. Os programas escritos em uma linguagem interpretada são executados diretamente do código-fonte, sem nenhuma etapa intermediária de compilação.

5. O que é PEP 8 e por que é importante?

PEP significa Proposta de aprimoramento Python. Um PEP é um documento oficial de design que fornece informações para a comunidade Python ou descreve um novo recurso para Python ou seus processos. PEP 8 é especialmente importante, pois documenta as diretrizes de estilo para o código Python. Aparentemente, contribuir com a comunidade de código aberto Python requer que você siga essas diretrizes de estilo com sinceridade e rigor.

6. Como a memória é gerenciada no Python?

O gerenciamento de memória em Python é feito pelo Python Memory Manager. A memória alocada pelo gerente está na forma de um espaço de pilha privado dedicado para Python. Todos os objetos Python são armazenados neste heap e, sendo privados, são inacessíveis para o programador. Porém, o python fornece algumas funções básicas da API para trabalhar no espaço de heap privado.
Além disso, o Python tem uma coleta de lixo embutida para reciclar a memória não utilizada para o espaço de heap privado.

7. O que são namespaces Python? Por que eles são usados?

  • Namespace local inclui nomes locais dentro de uma função. o namespace é criado temporariamente para uma chamada de função e é limpo quando a função retorna.
  • Namespace global inclui nomes de vários pacotes / módulos importados que estão sendo usados ​​no projeto atual. Este namespace é criado quando o pacote é importado no script e dura até a execução do script.
  • Namespace integrado inclui funções integradas do Python central e nomes integrados para vários tipos de exceções.

8. O que é escopo em Python?

  • UMA escopo local refere-se aos objetos locais disponíveis na função atual.
  • UMA Âmbito global refere-se aos objetos disponíveis durante a execução do código desde o seu início.
  • UMA escopo em nível de módulo refere-se aos objetos globais do módulo atual acessíveis no programa.
  • Um escopo mais externo refere-se a todos os nomes internos que podem ser chamados no programa. Os objetos neste escopo são pesquisados ​​por último para encontrar o nome referenciado.

9. O que é resolução de escopo em Python?

  • Os módulos Python, nomeadamente 'math' e 'cmath', têm várias funções comuns a ambos - log10 (), acos (), exp () etc. Para resolver esta ambiguidade, é necessário prefixá-los com os respectivos módulo, como math.exp () e cmath.exp ().
  • Considere o código abaixo, um objeto temporário foi inicializado para 10 globalmente e depois para 20 na chamada de função. No entanto, a chamada de função não alterou o valor da temperatura globalmente. Aqui, podemos observar que o Python traça uma linha clara entre as variáveis ​​globais e locais, tratando seus namespaces como identidades separadas.

Esse comportamento pode ser substituído usando a palavra-chave global dentro da função, conforme mostrado no exemplo a seguir:

10. O que são decoradores em Python?

Decoradores em Python são essencialmente funções que adicionam funcionalidade a uma função existente em Python sem alterar a estrutura da própria função. Eles são representados pelo @decorator_name em Python e são chamados de baixo para cima. Por exemplo:

A beleza dos decoradores está no fato de que além de agregar funcionalidade à saída do método, eles podem até aceitar argumentos para funções e pode modificar ainda mais esses argumentos antes de passá-los para a própria função. O função aninhada interna, ou seja, a função de 'invólucro', desempenha um papel significativo aqui. É implementado para fazer cumprir encapsulamento e, assim, manter-se oculto do âmbito global.

11. O que são listas e tuplas? Qual é a principal diferença entre os dois?

Listas e Tuplas são ambos tipos de dados de sequência que pode armazenar uma coleção de objetos em Python. Os objetos armazenados em ambas as sequências podem ter diferentes tipos de dados. As listas são representadas com colchetes ['sara', 6, 0,19], enquanto as tuplas são representadas com parênteses ('ansh', 5, 0,97).
Mas qual é a diferença real entre os dois? A principal diferença entre os dois é que enquanto listas são mutáveis, tuplas por outro lado são imutáveis objetos. Isso significa que as listas podem ser modificadas, acrescentadas ou divididas em movimento, mas as tuplas permanecem constantes e não podem ser modificadas de nenhuma maneira. Você pode executar o seguinte exemplo no Python IDLE para confirmar a diferença:

12. O que são compreensões Dict e List?

Compreensões Python, como decoradores, são açúcar sintático construções que ajudam construção alterada e filtrada listas, dicionários ou conjuntos de uma determinada lista, dicionário ou conjunto. O uso de compreensões economiza muito tempo e código que pode ser consideravelmente mais detalhado (contendo mais linhas de código). Vejamos alguns exemplos, onde as compreensões podem ser verdadeiramente benéficas:

  • Executar operações matemáticas em toda a lista
  • Executar operações de filtragem condicional em toda a lista
  • Combinando várias listas em uma
    As abrangências permitem vários iteradores e, portanto, podem ser usadas para combinar várias listas em uma.
  • Achatando uma lista multidimensional
    Uma abordagem semelhante de iteradores aninhados (como acima) pode ser aplicada para nivelar uma lista multidimensional ou trabalhar em seus elementos internos.

Observação: As compreensões de lista têm o mesmo efeito que o método de mapa em outras línguas. Eles seguem o notação matemática de construtor de conjunto em vez de mapear e filtrar funções em Python.

13. Quais são os tipos de dados integrados comuns em Python?

Existem vários tipos de dados integrados em Python. Embora o Python não exija que os tipos de dados sejam definidos explicitamente durante as declarações de variáveis, é provável que ocorram erros de tipo se o conhecimento dos tipos de dados e sua compatibilidade entre si forem negligenciados. Python fornece funções type () e isinstance () para verificar o tipo dessas variáveis. Esses tipos de dados podem ser agrupados nas seguintes categorias-

  • Tipo Nenhum
    Nenhuma palavra-chave representa os valores nulos em Python. A operação de igualdade booleana pode ser executada usando esses objetos NoneType.
    Nome da classeDescrição
    NoneTypeRepresenta o NULO valores em Python

  • Tipos Numéricos
    Existem três tipos numéricos distintos - inteiros, Números de ponto flutuante, e números complexos. Adicionalmente, booleanos são um subtipo de inteiros.
    Nome da classeDescrição
    intArmazena literais inteiros, incluindo hex, octal e números binários como inteiros
    flutuadorArmazena literais contendo valores decimais e / ou sinal de expoente como números de ponto flutuante
    complexoArmazena número complexo na forma (A + Bj) e possui atributos: real e imag
    boolArmazena o valor booleano (verdadeiro ou falso)
    Observação: A biblioteca padrão também inclui frações para armazenar números racionais e decimal para armazenar números de ponto flutuante com precisão definida pelo usuário.

14. O que é lambda em Python? Por que é usado?

  • Atribuição de funções lambda a uma variável
  • Envolvendo funções lambda dentro de outra função

15. O que é passagem em Python?

A palavra-chave pass representa uma operação nula em Python. Geralmente é usado com o propósito de preencher blocos vazios de código que podem ser executados durante a execução, mas ainda não foram escritos. Sem o passar declaração no código a seguir, podemos encontrar alguns erros durante a execução do código.

16. Como você copia um objeto em Python?

Em Python, a instrução de atribuição ( = operador) não copia objetos. Em vez disso, ele cria uma ligação entre o objeto existente e o nome da variável de destino. Para criar cópias de um objeto em Python, precisamos usar o cópia de módulo. Além disso, existem duas maneiras de criar cópias para o determinado objeto usando o cópia de módulo -

  • Cópia Rasa é uma cópia bit a bit de um objeto. O objeto copiado criado possui uma cópia exata dos valores do objeto original. Se algum dos valores forem referências a outros objetos, apenas os endereços de referência dos mesmos serão copiados.
  • Deep Copy copia todos os valores recursivamente do objeto de origem para o objeto de destino, ou seja, até mesmo duplica os objetos referenciados pelo objeto de origem.

17. Qual é a diferença entre xrange e range em Python?

xrange () e alcance() são bastante semelhantes em termos de funcionalidade. Ambos geram uma sequência de inteiros, com a única diferença de que range () retorna um Lista Python, enquanto xrange () retorna um objeto xrange.

Então, como isso faz diferença? Com certeza, porque ao contrário de range (), xrange () não gera uma lista estática, ele cria o valor em movimento. Esta técnica é comumente usada com um tipo de objeto geradores e foi denominado como "produzindo".

Produzindo é crucial em aplicativos onde a memória é uma restrição. Criar uma lista estática como em range () pode levar a um Erro de Memória em tais condições, enquanto xrange () pode lidar com isso de forma otimizada usando apenas memória suficiente para o gerador (significativamente menos em comparação).

Observação: xrange foi descontinuada a partir de Python 3.x. Agora, range faz exatamente o mesmo que xrange costumava fazer em Python 2.x, já que era muito melhor usar xrange () do que a função range () original no Python 2.x.

18. O que são módulos e pacotes em Python?

Pacotes Python e módulos Python são dois mecanismos que permitem programação modular em Python. A modularização tem várias vantagens -

  • Simplicidade: Trabalhar em um único módulo ajuda você a se concentrar em uma parte relativamente pequena do problema em questão. Isso torna o desenvolvimento mais fácil e menos sujeito a erros.
  • Capacidade de manutenção: Os módulos são projetados para impor limites lógicos entre diferentes domínios de problemas. Se eles forem escritos de uma maneira que reduza a interdependência, é menos provável que as modificações em um módulo possam impactar outras partes do programa.
  • Reutilização: As funções definidas em um módulo podem ser facilmente reutilizadas por outras partes do aplicativo.
  • Escopo: Módulos normalmente definem um separado namespace, o que ajuda a evitar confusão entre identificadores de outras partes do programa.

Módulos, em geral, são simplesmente arquivos Python com extensão .py e podem ter um conjunto de funções, classes ou variáveis ​​definidas e implementadas. Eles podem ser importados e inicializados uma vez usando a instrução import. If partial functionality is needed, import the requisite classes or functions using from foo import bar .

Packages allow for hierarchial structuring of the module namespace using dot notation. As, modules help avoid clashes between global variable names, in a similary manner, pacotes help avoid clashes between module names.
Creating a package is easy since it makes use of the system's inherent file structure. So just stuff the modules into a folder and there you have it, the folder name as the package name. Importing a module or its contents from this package requires the package name as prefix to the module name joined by a dot.

Observação: You can technically import the package as well, but alas, it doesn't import the modules within the package to the local namespace, thus, it is practically useless.

19. What are global, protected and private attributes in Python?

  • Global variables are public variables that are defined in the global scope. To use the variable in the global scope inside a function, we use the global keyword.
  • Protected attributes are attributes defined with a underscore prefixed to their identifier eg. _sara. They can still be accessed and modified from outside the class they are defined in but a responsible developer should refrain from doing so.
  • Privado attributes are attributes with double underscore prefixed to their identifier eg. __ansh. They cannot be accessed or modified from the outside directly and will result in an AttributeError if such an attempt is made.

20. What is self in Python?

Self is a keyword in Python used to define an instance or an object of a class. In Python, it is explicity used as the first paramter, unlike in Java where it is optional. It helps in disinguishing between the methods and attributes of a class from its local variables.

21. What is __init__?

__init__ is a contructor method in Python and is automatically called to allocate memory when a new object/instance is created. All classes have a __iniciar__ method associated with them. It helps in distinguishing methods and attributes of a class from local variables.

22. What is break, continue and pass in Python?

Quebrar The break statement terminates the loop immediately
and the control flows to the statement after the body of the loop.
Continuar The continue statement terminates the current iteration of the statement,
skips the rest of the code in the current iteration and the control flows to the next iteration of the loop.
Passar As explained above, pass keyword in Python is generally used to fill-up empty blocks
and is similar to an empty statement represented by a semi-colon in languages such as Java, C++, Javascript etc.

23. What is pickling and unpickling?

Python library offers a feature - serialization out of the box. Serializing a object refers to transforming it into a format that can be stored, so as to be able to deserialize it later on, to obtain the original object. Here, the salmoura module comes into play.

Decapagem
Pickling is the name of the serialization process in Python. Any object in Python can be serialized into a byte stream and dumped as a file in the memory. The process of pickling is compact but pickle objects can be compressed further. Moreover, pickle keeps track of the objects it has serialized and the serialization is portable across versions.
The function used for the above process is pickle.dump() .

Unpickling
Unpickling is the complete inverse of pickling. It deserializes the byte stream to recreate the objects stored in the file, and loads the object to memory.
The function used for the above process is pickle.load() .

Observação: Python has another, more primitive, serialization module called marshall, which exists primarily to support .pyc files in Python and differs significantly from pickle.

24. What are generators in Python?

Generators are functions that return an iterable collection of items, one at a time, in a set manner. Generators, in general, are used to create iterators with a different approach. They employ the use of yield keyword rather than return to return a generator object.
Let's try and build a generator for fibonacci numbers -

25. What is PYTHONPATH in Python?

PYTHONPATH is an environment variable which you can set to add additional directories where Python will look for modules and packages. This is especially useful in maintaining Python libraries that you do not wish to install in the global default location.


You should consider adding a main function to your project. This is usually done through the introduction of:

This allows for me to import your project and not have it automatically execute the game function at the bottom. Increasing re-usability.

1 For instance, It may be the project defaults to "" , but you need to print out " Hi " with the quotes, so print('" Hi "') may be chosen.

In addition to another answer I will add these places to improve (I will not repeat all things from that answer, my answer is just an addition):

1. Code inconsistency

You have several places in your code where your code is inconsistent

Both functions are checking collisions but one returns integer (0/1) and another - boolean (True/False).

For head you convert X*block_size to int (it is unnecessary anyway). For body you don't do it.

I recommend you to always check your code for possible inconsistency.

2. Names inconsistency

I moved it to an another point because it is not about how your code works - it is about how another programmers will read your code.

You use three different namings for direction entity:

Isto é distante better to use consistent variable names. If you are using different direction variables, get them names with only one word for directions. Here is the example:

3. Small code improvements

Sometimes you look at your code and think: "Hmmm, it is working but looks not good". Often in these cases you can slightly reorganize your code to make it a bit better :)

This line of code is correct too but it is hard to read:

But it will be far better to read if you will change it to:

or even this (sometimes I use it for really long if's):

You never read size , and Python Lists already know their own length in case you did need it.

You're just duplicating functionality that List already gives you by manually keeping size in sync with the list length.

Separate game logic from screen rendering details

You keep snake coordinates scaled by pixels. This seems to complicate your code everywhere with block_size instead of 1 I suspect it would be easier to keep snake coordinates in units of blocks, and only scale to pixels for drawing purposes.

por exemplo. then your outer-wall check could be something like s.head[0] >= bg_width instead of
s.head[0] > bg_width-block_size .

1 is special for integers because it's the difference between > and >=

I like your add_to_tail idea of putting multiple snake segments in the same place initially, so move on future turns actually makes the snake longer on screen. That high-level design might be worthy of a comment.

The other option would be a "future growth" counter that you check (and decrement) every move to decide whether to remove the last tail block. (That's what I was expecting because I hadn't thought of your idea). Your way is more efficient and will still work if you want food to cause multiple segments of growth. You can still do them all when the food is eaten.

Keeping a separate head : I'm not sure this is helping you. Functions that want to look at the first segment can do head = snake_.body[0] .

I don't understand why move needs to do this:

when it looks to me like inserting the modified head as a new first element will already create that condition. So either this is redundant (and confusing), or else it's extra work that you wouldn't need to do if you didn't redundantly keep the head coordinates in 2 places. (Front of the List, and in its own object.)

This should be an enum or integer, not a string. String compares are fairly cheap, but not as cheap as integers. There's no reason that a direction needs to be an arbitrary string when it can take only 1 of 4 possible values. A string isn't making your code any easier to read.

You probably still want the if/elif chain to turn a direction into an x or y offset, but another option for an integer would be a lookup table of [-1, 0] , [1, 0] etc. so you look up the x and y offsets for the given direction and just add them to the head's x and y coordinates without any conditionals.

Or direction could actually be an XY vector, removing the lookup step.

But that might complicate change_dir . Or give you a different implementation: to check for reversing direction: if new_dir + old_dir == [0,0] then you tried to double back. Otherwise you posso set dir = new_dir .

I like your design for having the keyboard-input just call change_dir to check the game-logic of that input. That works very cleanly, and would still work if left was defined as [-1, 0] instead of "LEFT" .