O Manual do Python segue a regra 80/20: aprenda 80% do tópico em 20% do tempo.
Acho que essa abordagem oferece uma visão geral completa.
Este livro não pretende cobrir todos os aspectos relacionados ao Python. Ele se concentra no cerne da linguagem, tentando simplificar os tópicos mais complexos.
Espero que o conteúdo deste livro ajude você a alcançar o que deseja: aprender o básico do Python .
Nota: Você pode obter uma versão em PDF, ePub e Mobi deste Manual do Python
Aproveitar!
Resumo
- Introdução ao Python
- Como instalar o Python
- Como executar programas em Python
- Python 2 vs Python 3
- Noções básicas de Python
- Tipos de dados em Python
- Operadores em Python
- O operador ternário em Python
- Strings em Python
- Booleanos em Python
- Números em Python
- Constantes em Python
- Enumerações em Python
- Entrada do usuário em Python
- Instruções de controle em Python
- Listas em Python
- Duplos em Python
- Dicionários em Python
- Conjuntos em Python
- Funções em Python
- Objetos em Python
- Laços em Python
- Aulas em Python
- Módulos em Python
- A Biblioteca Padrão do Python
- Guia de Estilo Python PEP8
- Depuração em Python
- Escopo de Variáveis em Python
- Como aceitar argumentos da linha de comando em Python
- Funções Lambda em Python
- Recursão em Python
- Funções aninhadas em Python
- Fechamentos em Python
- Decoradores em Python
- Docstrings em Python
- Introspecção em Python
- Anotações em Python
- Exceções em Python
- A instrução with em Python
- Como instalar pacotes de terceiros em Python usando pip
- Compreensões de lista em Python
- Polimorfismo em Python
- Sobrecarga de operadores em Python
- Ambientes virtuais em Python
- Conclusão
Introdução ao Python
Python está literalmente devorando o mundo da programação. Sua popularidade e uso estão crescendo de maneiras sem precedentes na história da computação.
Python se destaca em uma ampla variedade de cenários – scripts de shell , automação de tarefas e desenvolvimento web são apenas alguns exemplos básicos.
Python é a linguagem escolhida para análise de dados e aprendizado de máquina , mas também pode se adaptar para criar jogos e trabalhar com dispositivos embarcados.
Mais importante ainda, é a língua escolhida para cursos introdutórios de ciência da computação em universidades do mundo todo.
Muitos estudantes aprendem Python como sua primeira linguagem de programação. Muitos estão aprendendo agora e muitos outros aprenderão no futuro. E para muitos deles, Python será a única linguagem de programação de que precisarão.
Graças a essa posição única, o Python provavelmente crescerá ainda mais no futuro.
A linguagem é simples, expressiva e bastante direta.
O ecossistema é enorme. Parece haver uma biblioteca para tudo o que você possa imaginar.
Python é uma linguagem de programação de alto nível adequada para iniciantes graças à sua sintaxe intuitiva, sua enorme comunidade e seu ecossistema vibrante.
Também é apreciado por profissionais de muitas áreas diferentes.
Tecnicamente falando, Python é uma linguagem interpretada que não tem uma fase intermediária de compilação como uma linguagem compilada, por exemplo C ou Java.
E, como muitas linguagens interpretadas, ela é tipada dinamicamente. Isso significa que você não precisa indicar os tipos das variáveis que usa, e as variáveis não estão vinculadas a um tipo específico.
Isso tem prós e contras. Em particular, você escreve programas mais rápido, mas, por outro lado, tem menos ajuda das ferramentas para evitar possíveis bugs. Isso significa que você só descobrirá certos problemas executando o programa em tempo de execução.
Python suporta uma ampla variedade de paradigmas de programação, incluindo programação procedural, programação orientada a objetos e programação funcional. É flexível o suficiente para se adaptar a diversas necessidades.
Criado em 1991 por Guido van Rossum, sua popularidade vem crescendo, especialmente nos últimos 5 anos, como mostra este infográfico do Google Trends:
Começar com Python é muito fácil. Tudo o que você precisa é instalar o pacote oficial do python.org, para Windows, macOS ou Linux, e pronto.
Se você é novo em programação, nos próximos posts vou te guiar para ir do zero até se tornar um programador Python.
E mesmo que você seja atualmente um programador especializado em outra linguagem, Python é uma linguagem que vale a pena conhecer, porque acredito que ela só vai crescer a partir daqui.
Linguagens de nível mais baixo, como C++ e Rust, podem ser ótimas para programadores experientes, mas são assustadoras no começo e levam muito tempo para serem dominadas.
Python, por outro lado, é uma linguagem de programação para todos: estudantes, pessoas que trabalham com Excel, cientistas e muito mais.
É a linguagem que todos os interessados em codificação deveriam aprender primeiro .
Como instalar o Python
Acesse https://www.python.org , escolha o menu Downloads, escolha seu sistema operacional e um painel com um link para baixar o pacote oficial aparecerá:
Certifique-se de seguir as instruções específicas para o seu sistema operacional. No macOS, você pode encontrar um guia detalhado em https://flaviocopes.com/python-installation-macos/ .
Como executar programas em Python
Existem algumas maneiras diferentes de executar programas Python.
Em particular, há uma distinção entre usar prompts interativos, onde você digita um código Python e ele é executado imediatamente, e salvar um programa Python em um arquivo e executá-lo.
Vamos começar com prompts interativos.
Se você abrir seu terminal e digitar python
, verá uma tela como esta:
Este é o REPL (Leitura-Avaliação-Impressão-Loop) do Python.
Observe o >>>
símbolo e o cursor depois dele. Você pode digitar qualquer código Python aqui e pressionar a enter
tecla para executá-lo.
Por exemplo, tente definir uma nova variável usando
name = "Flavio"
e então imprima seu valor, usando print()
:
print(name)
Observação: no REPL, você também pode simplesmente digitar
name
, pressionar aenter
tecla e obter o valor de volta. Mas, em um programa, você não verá nenhuma saída se fizer isso - você precisa usarprint()
.
Qualquer linha de Python que você escrever aqui será executada imediatamente.
Digite quit()
para sair deste REPL Python.
Você pode acessar o mesmo prompt interativo usando o aplicativo IDLE que é instalado automaticamente pelo Python:
Isso pode ser mais conveniente para você porque com o mouse você pode se mover e copiar/colar mais facilmente do que com o terminal.
Esses são os princípios básicos que vêm com o Python por padrão. No entanto, recomendo que você instale o IPython , provavelmente o melhor aplicativo REPL de linha de comando que você pode encontrar.
Instale-o com
pip install ipython
Certifique-se de que os binários do pip estejam no seu caminho e execute ipython
:
ipython
é outra interface que permite trabalhar com um REPL Python e fornece alguns recursos interessantes, como destaque de sintaxe, conclusão de código e muito mais.
A segunda maneira de executar um programa Python é escrever o código do programa Python em um arquivo, por exemplo program.py
:
e então execute-o com python program.py
:
Observe que salvamos programas Python com a
.py
extensão - isso é uma convenção.
Neste caso, o programa é executado como um todo, não uma linha de cada vez. E é assim que normalmente executamos programas.
Usamos o REPL para prototipagem rápida e para aprendizado.
No Linux e no macOS, um programa Python também pode ser transformado em um script de shell, acrescentando a todo seu conteúdo uma linha especial que indica qual executável usar para executá-lo.
No meu sistema, o executável Python está localizado em /usr/bin/python3
, então eu digito #!/usr/bin/python3
na primeira linha:
Então posso definir a permissão de execução no arquivo:
chmod u+x program.py
e posso executar o programa com
./program.py
Isso é especialmente útil quando você escreve scripts que interagem com o terminal.
Temos muitas outras maneiras de executar programas Python.
Uma delas é usar o VS Code, e em particular a extensão oficial do Python da Microsoft:
Após instalar esta extensão, você terá o preenchimento automático de código Python e verificação de erros, formatação automática e verificação de código com pylint
e alguns comandos especiais, incluindo:
Python: Inicie o REPL para executar o REPL no terminal integrado:
Python: Executar arquivo Python no terminal para executar o arquivo atual no terminal:
Python: Executar arquivo atual na janela interativa do Python :
e muito mais. Basta abrir a paleta de comandos (Exibir -> Paleta de Comandos ou Cmd-Shift-P) e digitar python
para ver todos os comandos relacionados ao Python:
Outra maneira de executar código Python facilmente é usar repl.it, um site muito bom que fornece um ambiente de codificação no qual você pode criar e executar seus aplicativos, em qualquer linguagem, incluindo Python:
Cadastre-se (é grátis) e, em "criar um repl", clique em Python:
e imediatamente será mostrado um editor com um main.py
arquivo, pronto para ser preenchido com muito código Python:
Depois de ter algum código, clique em "Executar" para executá-lo no lado direito da janela:
Acho que o repl.it é útil porque:
- você pode compartilhar o código facilmente apenas compartilhando o link
- várias pessoas podem trabalhar no mesmo código
- pode hospedar programas de longa duração
- você pode instalar pacotes
- ele fornece um banco de dados de chave-valor para aplicativos mais complexos
Python 2 vs Python 3
Um tópico importante que devemos abordar, desde o início, é a discussão Python 2 vs Python 3.
O Python 3 foi introduzido em 2008 e está em desenvolvimento como a versão principal do Python, enquanto o Python 2 continuou sendo mantido com correções de bugs e patches de segurança até o início de 2020.
Naquela data, o suporte ao Python 2 foi descontinuado.
Muitos programas ainda são escritos em Python 2, e as organizações ainda trabalham ativamente neles, porque a migração para Python 3 não é trivial e exigiria muito trabalho para atualizar esses programas. E migrações grandes e importantes sempre introduzem novos bugs.
Mas o código novo, a menos que você tenha que aderir às regras definidas pela sua organização que forçam o Python 2, deve sempre ser escrito em Python 3.
Este livro se concentra no Python 3.
Noções básicas de Python
Variáveis em Python
Podemos criar uma nova variável Python atribuindo um valor a um rótulo, usando o =
operador de atribuição.
Neste exemplo, atribuímos uma string com o valor "Roger" ao name
rótulo:
name = "Roger"
Aqui está um exemplo com um número:
age = 8
Um nome de variável pode ser composto por caracteres, números e o _
caractere sublinhado. Não pode começar com um número. Estes são todos nomes de variáveis válidos :
name1
AGE
aGE
a11111
my_name
_name
Estes são nomes de variáveis inválidos :
123
test!
name%
Fora isso, qualquer coisa é válida, a menos que seja uma palavra-chave Python . Existem algumas palavras-chave como for
, if
, while
e import
mais.
Não há necessidade de memorizá-los, pois o Python irá alertá-lo se você usar um deles como variável, e você gradualmente os reconhecerá como parte da sintaxe da linguagem de programação Python.
Expressões e declarações em Python
Podemos expressar qualquer tipo de código que retorne um valor. Por exemplo
1 + 1
"Roger"
Uma instrução, por outro lado, é uma operação sobre um valor. Por exemplo, estas são duas instruções:
name = "Roger"
print(name)
Um programa é formado por uma série de instruções. Cada instrução é colocada em sua própria linha, mas você pode usar ponto e vírgula para ter mais de uma instrução em uma única linha:
name = "Roger"; print(name)
Comentários
Em um programa Python, tudo após uma marca de hash é ignorado e considerado um comentário:
#this is a commented line
name = "Roger" # this is an inline comment
Recuo em Python
O recuo em Python é significativo.
Você não pode recuar aleatoriamente assim:
name = "Flavio"
print(name)
Algumas outras linguagens não têm espaços em branco significativos, mas em Python, o recuo é importante.
Nesse caso, se você tentar executar este programa, receberá um IndentationError: unexpected indent
erro, porque o recuo tem um significado especial.
Tudo o que é recuado pertence a um bloco, como uma instrução de controle ou um bloco condicional, ou um corpo de função ou classe. Veremos mais sobre isso mais adiante.
Tipos de dados em Python
O Python tem vários tipos integrados.
Se você criar a name
variável atribuindo a ela o valor "Roger", automaticamente essa variável agora representa um tipo de dado String .
name = "Roger"
Você pode verificar o tipo de uma variável usando a type()
função, passando a variável como um argumento e então comparando o resultado com str
:
name = "Roger"
type(name) == str #True
Ou usando isinstance()
:
name = "Roger"
isinstance(name, str) #True
Observe que para ver o
True
valor em Python, fora de um REPL, você precisa encapsular esse código dentro deprint()
, mas para maior clareza, evito usá-lo.
Usamos a str
classe aqui, mas o mesmo funciona para outros tipos de dados.
Primeiro, temos os números. Números inteiros são representados usando a int
classe . Números de ponto flutuante (frações) são do tipo float
:
age = 1
type(age) == int #True
fraction = 0.1
type(fraction) == float #True
Você viu como criar um tipo a partir de um literal de valor, assim:
name = "Flavio"
age = 20
O Python detecta automaticamente o tipo a partir do tipo de valor.
Você também pode criar uma variável de um tipo específico usando o construtor de classe, passando um literal de valor ou um nome de variável:
name = str("Flavio")
anotherName = str(name)
Você também pode converter de um tipo para outro usando o construtor de classe. O Python tentará determinar o valor correto, por exemplo, extraindo um número de uma string:
age = int("20")
print(age) #20
fraction = 0.1
intFraction = int(fraction)
print(intFraction) #0
Isso se chama conversão . É claro que essa conversão pode nem sempre funcionar, dependendo do valor passado. Se você escrever test
"em vez de" 20
na string acima, receberá um ValueError: invalid literal for int() with base 10: 'test'
erro.
Esses são apenas os conceitos básicos de tipos. Temos muito mais tipos em Python:
complex
para números complexosbool
para booleanoslist
para listastuple
para casaisrange
para intervalosdict
para dicionáriosset
para conjuntos
e muito mais!
Exploraremos todos eles em breve.
Operadores em Python
Operadores Python são símbolos que usamos para executar operações em valores e variáveis.
Podemos dividir os operadores com base no tipo de operação que realizam:
- operador de atribuição
- operadores aritméticos
- operadores de comparação
- operadores lógicos
- operadores bit a bit
além de alguns interessantes como is
e in
.
Operador de atribuição em Python
O operador de atribuição é usado para atribuir um valor a uma variável:
age = 8
Ou para atribuir um valor de variável a outra variável:
age = 8
anotherVariable = age
Desde o Python 3.8, o :=
operador walrus é usado para atribuir um valor a uma variável como parte de outra operação. Por exemplo, dentro de um if
ou na parte condicional de um loop. Mais sobre isso depois.
Operadores aritméticos em Python
Python tem vários operadores aritméticos: +
, -
, *
, /
(divisão), %
(resto), **
(exponenciação) e //
(divisão de base):
1 + 1 #2
2 - 1 #1
2 * 2 #4
4 / 2 #2
4 % 3 #1
4 ** 2 #16
4 // 2 #2
Observe que você não precisa de espaço entre os operandos, mas é bom para facilitar a leitura.
-
também funciona como um operador menos unário:
print(-4) #-4
+
também é usado para concatenar valores de String:
"Roger" + " is a good dog"
#Roger is a good dog
Podemos combinar o operador de atribuição com operadores aritméticos:
+=
-=
*=
/=
%=
- ...e assim por diante
Exemplo:
age = 8
age += 1
# age is now 9
Operadores de comparação em Python
Python define alguns operadores de comparação:
==
!=
>
<
>=
<=
Você pode usar esses operadores para obter um valor booleano ( True
ou False
) dependendo do resultado:
a = 1
b = 2
a == b #False
a != b #True
a > b #False
a <= b #True
Operadores booleanos em Python
Python nos dá os seguintes operadores booleanos:
not
and
or
Ao trabalhar com atributos True
ou False
, eles funcionam como AND, OR e NOT lógicos e são frequentemente usados na if
avaliação de expressões condicionais:
condition1 = True
condition2 = False
not condition1 #False
condition1 and condition2 #False
condition1 or condition2 #True
Caso contrário, preste atenção a uma possível fonte de confusão:
or
usado em uma expressão retorna o valor do primeiro operando que não é um valor falso ( False
, 0
, ''
, []
..). Caso contrário, retorna o último operando.
print(0 or 1) ## 1
print(False or 'hey') ## 'hey'
print('hi' or 'hey') ## 'hi'
print([] or False) ## 'False'
print(False or []) ## '[]'
A documentação do Python o descreve como if x is false, then y, else x
.
and
Avalia o segundo argumento somente se o primeiro for verdadeiro. Portanto, se o primeiro argumento for falso ( False
, 0
, ''
, []
..), ele retorna esse argumento. Caso contrário, ele avalia o segundo argumento:
print(0 and 1) ## 0
print(1 and 0) ## 0
print(False and 'hey') ## False
print('hi' and 'hey') ## 'hey'
print([] and False ) ## []
print(False and [] ) ## False
A documentação do Python o descreve como if x is false, then x, else y
.
Operadores bit a bit em Python
Alguns operadores são usados para trabalhar com bits e números binários:
&
executa AND binário|
executa OR binário^
executa uma operação XOR binária~
executa uma operação binária NOT<<
operação de deslocamento para a esquerda>>
operação de deslocamento para a direita
Operadores bit a bit raramente são usados, apenas em situações muito específicas, mas vale a pena mencioná-los.
is
e in
em Python
is
é chamado de operador de identidade . É usado para comparar dois objetos e retorna verdadeiro se ambos forem o mesmo objeto. Mais sobre objetos posteriormente.
in
É chamado de operador de pertinência . É usado para indicar se um valor está contido em uma lista ou em outra sequência. Mais sobre listas e outras sequências posteriormente.
O operador ternário em Python
O operador ternário em Python permite que você defina rapidamente uma condicional.
Digamos que você tenha uma função que compara uma age
variável ao 18
valor e retorna Verdadeiro ou Falso, dependendo do resultado.
Em vez de escrever:
def is_adult(age):
if age > 18:
return True
else:
return False
Você pode implementá-lo com o operador ternário desta maneira:
def is_adult(age):
return True if age > 18 else False
Primeiro você define o resultado se a condição for Verdadeira, depois você avalia a condição e então define o resultado se a condição for Falsa:
<result_if_true> if <condition> else <result_if_false>
Strings em Python
Uma string em Python é uma série de caracteres entre aspas ou aspas duplas:
"Roger"
'Roger'
Você pode atribuir um valor de string a uma variável:
name = "Roger"
Você pode concatenar duas strings usando o +
operador:
phrase = "Roger" + " is a good dog"
Você pode anexar a uma string usando +=
:
name = "Roger"
name += " is a good dog"
print(name) #Roger is a good dog
Você pode converter um número em uma string usando o str
construtor de classe:
str(8) #"8"
Isso é essencial para concatenar um número a uma string:
print("Roger is " + str(8) + " years old") #Roger is 8 years old
Uma string pode ser multilinha quando definida com uma sintaxe especial, colocando a string entre um conjunto de 3 aspas:
print("""Roger is
8
years old
""")
#double quotes, or single quotes
print('''
Roger is
8
years old
''')
Uma string tem um conjunto de métodos integrados, como:
isalpha()
para verificar se uma string contém apenas caracteres e não está vaziaisalnum()
para verificar se uma string contém caracteres ou dígitos e não está vaziaisdecimal()
para verificar se uma string contém dígitos e não está vazialower()
para obter uma versão minúscula de uma stringislower()
para verificar se uma string é minúsculaupper()
para obter uma versão maiúscula de uma stringisupper()
para verificar se uma string é maiúsculatitle()
para obter uma versão maiúscula de uma stringstartsswith()
para verificar se a string começa com uma substring específicaendswith()
para verificar se a string termina com uma substring específicareplace()
para substituir uma parte de uma stringsplit()
para dividir uma string em um separador de caracteres específicostrip()
para cortar o espaço em branco de uma stringjoin()
para acrescentar novas letras a uma stringfind()
para encontrar a posição de uma substring
e muitos mais.
Nenhum desses métodos altera a string original. Em vez disso, eles retornam uma nova string modificada. Por exemplo:
name = "Roger"
print(name.lower()) #"roger"
print(name) #"Roger"
Você também pode usar algumas funções globais para trabalhar com strings.
Em particular, penso em len()
, que fornece o comprimento de uma string:
name = "Roger"
print(len(name)) #5
O in
operador permite que você verifique se uma string contém uma substring:
name = "Roger"
print("ger" in name) #True
Escapar é uma maneira de adicionar caracteres especiais a uma string.
Por exemplo, como você adiciona aspas duplas em uma string que está entre aspas duplas?
name = "Roger"
"Ro"Ger"
não funcionará, pois o Python pensará que a string termina em "Ro"
.
A maneira de fazer isso é escapar as aspas duplas dentro da string, com o caractere de barra invertida:
name = "Ro"ger"
Isso se aplica também a aspas simples '
e a caracteres de formatação especiais, como
tabulação,
nova linha e barra invertida.
Dada uma string, você pode obter seus caracteres usando colchetes para obter um item específico, dado seu índice, começando em 0:
name = "Roger"
name[0] #'R'
name[1] #'o'
name[2] #'g'
Usar um número negativo iniciará a contagem a partir do final:
name = "Roger"
name[-1] #"r"
Você também pode usar um intervalo, usando o que chamamos de fatiamento :
name = "Roger"
name[0:2] #"Ro"
name[:2] #"Ro"
name[2:] #"ger"
Booleanos em Python
O Python fornece o bool
tipo, que pode ter dois valores: True
e False
(em maiúsculas).
done = False
done = True
Os booleanos são especialmente úteis com estruturas de controle condicional, como if
instruções:
done = True
if done:
# run some code here
else:
# run some other code
Ao avaliar um valor para True
ou False
, se o valor não for a , bool
temos algumas regras dependendo do tipo que estamos verificando:
- os números são sempre
True
exceto o número0
- strings são
False
somente quando vazias - listas, tuplas, conjuntos e dicionários são usados
False
somente quando vazios
Você pode verificar se um valor é booleano desta maneira:
done = True
type(done) == bool #True
Ou usando isinstance()
, passando 2 argumentos: a variável e a bool
classe:
done = True
isinstance(done, bool) #True
A função global any()
também é muito útil ao trabalhar com booleanos, pois ela retorna True
se algum dos valores do iterável (lista, por exemplo) passado como argumento for True
:
book_1_read = True
book_2_read = False
read_any_book = any([book_1_read, book_2_read])
A função global all()
é a mesma, mas retorna True
se todos os valores passados a ela forem True
:
ingredients_purchased = True
meal_cooked = False
ready_to_serve = all([ingredients_purchased, meal_cooked])
Números em Python
Os números em Python podem ser de 3 tipos: int
, float
e complex
.
Números inteiros em Python
Números inteiros são representados usando a int
classe . Você pode definir um inteiro usando um literal de valor:
age = 8
Você também pode definir um número inteiro usando o int()
construtor:
age = int(8)
Para verificar se uma variável é do tipo int
, você pode usar a type()
função global:
type(age) == int #True
Números de ponto flutuante em Python
Números de ponto flutuante (frações) são do tipo float
. Você pode definir um inteiro usando um literal de valor:
fraction = 0.1
Ou usando o float()
construtor:
fraction = float(0.1)
Para verificar se uma variável é do tipo float
, você pode usar a type()
função global:
type(fraction) == float #True
Números complexos em Python
Números complexos são do tipo complex
.
Você pode defini-los usando um literal de valor:
complexNumber = 2+3j
ou usando o complex()
construtor:
complexNumber = complex(2, 3)
Depois de obter um número complexo, você pode obter sua parte real e imaginária:
complexNumber.real #2.0
complexNumber.imag #3.0
Novamente, para verificar se uma variável é do tipo complex
, você pode usar a type()
função global:
type(complexNumber) == complex #True
Operações aritméticas em números em Python
Você pode realizar operações aritméticas em números, usando os operadores aritméticos: +
, -
, *
, /
(divisão), %
(resto), **
(exponenciação) e //
(divisão por andar):
1 + 1 #2
2 - 1 #1
2 * 2 #4
4 / 2 #2
4 % 3 #1
4 ** 2 #16
4 // 2 #2
e você pode usar os operadores de atribuição compostos
+=
-=
*=
/=
%=
- ...e assim por diante
para executar operações rapidamente em variáveis também:
age = 8
age += 1
Funções internas em Python
Existem 2 funções integradas que ajudam com números:
abs()
retorna o valor absoluto de um número.
round()
dado um número, retorna seu valor arredondado para o inteiro mais próximo:
round(0.12) #0
Você pode especificar um segundo parâmetro para definir a precisão do ponto decimal:
round(0.12, 1) #0.1
Várias outras funções e constantes utilitárias matemáticas são fornecidas pela biblioteca padrão do Python:
- o
math
pacote fornece funções matemáticas gerais e constantes - o
cmath
pacote fornece utilitários para trabalhar com números complexos. - o
decimal
pacote fornece utilitários para trabalhar com decimais e números de ponto flutuante. - o
fractions
pacote fornece utilitários para trabalhar com números racionais.
Exploraremos alguns deles separadamente mais tarde.
Constantes em Python
O Python não tem como impor que uma variável deva ser uma constante.
O mais próximo que você pode chegar é usar uma enumeração:
class Constants(Enum):
WIDTH = 1024
HEIGHT = 256
E chegar a cada valor usando, por exemplo,Constants.WIDTH.value
.
Ninguém pode reatribuir esse valor.
Caso contrário, se você quiser confiar em convenções de nomenclatura, pode seguir esta: declare variáveis que nunca devem mudar para letras maiúsculas:
WIDTH = 1024
Ninguém impedirá que você sobrescreva esse valor, e o Python não impedirá isso.
É isso que a maioria dos códigos Python faz e que você verá.
Enumerações em Python
Enums são nomes legíveis que estão vinculados a um valor constante.
Para usar enums, importe Enum
do enum
módulo da biblioteca padrão:
from enum import Enum
Então você pode inicializar uma nova enumeração desta maneira:
class State(Enum):
INACTIVE = 0
ACTIVE = 1
Depois de fazer isso, você pode fazer referência State.INACTIVE
eState.ACTIVE
, e eles servem como constantes.
Agora, se você tentar imprimir, State.ACTIVE
por exemplo:
print(State.ACTIVE)
não retornará 1
, mas State.ACTIVE
.
O mesmo valor pode ser alcançado pelo número atribuído na enumeração: print(State(1))
retornará State.ACTIVE
. O mesmo vale para o uso da notação de colchetes State['ACTIVE']
.
No entanto, você pode obter o valor usando State.ACTIVE.value
.
Você pode listar todos os valores possíveis de uma enumeração:
list(State) # [<State.INACTIVE: 0>, <State.ACTIVE: 1>]
Você pode contá-los:
len(State) # 2
Entrada do usuário em Python
Em um aplicativo de linha de comando Python, você pode exibir informações ao usuário usando a print()
função:
name = "Roger"
print(name)
Também podemos aceitar a entrada do usuário, usando input()
:
print('What is your age?')
age = input()
print('Your age is ' + age)
Essa abordagem recebe a entrada em tempo de execução, o que significa que o programa interromperá a execução e esperará até que o usuário digite algo e pressione a enter
tecla.
Você também pode fazer um processamento de entrada mais complexo e aceitar a entrada no momento da invocação do programa, e veremos como fazer isso mais tarde.
Isso funciona para aplicativos de linha de comando. Outros tipos de aplicativos precisarão de uma maneira diferente de aceitar entradas.
Instruções de controle em Python
Quando você está lidando com booleanos e expressões que retornam um booleano em particular, podemos tomar decisões e seguir caminhos diferentes dependendo de seus True
valores False
.
Em Python, fazemos isso usando a if
instrução:
condition = True
if condition == True:
# do something
Quando o teste de condição é resolvido para True
, como no caso acima, seu bloco é executado.
O que é um bloco? Um bloco é a parte recuada um nível (geralmente 4 espaços) à direita:
condition = True
if condition == True:
print("The condition")
print("was true")
O bloco pode ser formado por uma única linha, ou várias linhas também, e termina quando você retorna ao nível de recuo anterior:
condition = True
if condition == True:
print("The condition")
print("was true")
print("Outside of the if")
Em combinação com if
você pode ter um else
bloco que é executado se o teste de condição dos if
resultados for False
:
condition = True
if condition == True:
print("The condition")
print("was True")
else:
print("The condition")
print("was False")
E você pode ter diferentes if
verificações vinculadas elif
que são executadas se a verificação anterior foi False
:
condition = True
name = "Roger"
if condition == True:
print("The condition")
print("was True")
elif name == "Roger":
print("Hello Roger")
else:
print("The condition")
print("was False")
O segundo bloco neste caso é executado se condition
for False
, e o name
valor da variável for "Roger".
Em uma if
declaração, você pode ter apenas uma if
verificação else
, mas várias séries de elif
verificações:
condition = True
name = "Roger"
if condition == True:
print("The condition")
print("was True")
elif name == "Roger":
print("Hello Roger")
elif name == "Syd":
print("Hello Syd")
elif name == "Flavio":
print("Hello Flavio")
else:
print("The condition")
print("was False")
if
e else
também pode ser usado em um formato inline, o que nos permite retornar um valor ou outro com base em uma condição.
Exemplo:
a = 2
result = 2 if a == 0 else 3
print(result) # 3
Listas em Python
Listas são uma estrutura de dados essencial do Python.
Eles permitem que você agrupe vários valores e referencie todos eles com um nome comum.
Por exemplo:
dogs = ["Roger", "Syd"]
Uma lista pode conter valores de diferentes tipos:
items = ["Roger", 1, "Syd", True]
Você pode verificar se um item está contido em uma lista com o in
operador:
print("Roger" in items) # True
Uma lista também pode ser definida como vazia:
items = []
Você pode referenciar os itens em uma lista pelo índice deles, começando do zero:
items[0] # "Roger"
items[1] # 1
items[3] # True
Usando a mesma notação, você pode alterar o valor armazenado em um índice específico:
items[0] = "Roger"
Você também pode usar o index()
método:
items.index(0) # "Roger"
items.index(1) # 1
Assim como acontece com strings, usar um índice negativo iniciará a pesquisa a partir do final:
items[-1] # True
Você também pode extrair uma parte de uma lista usando fatias:
items[0:2] # ["Roger", 1]
items[2:] # ["Syd", True]
Obtenha o número de itens contidos em uma lista usando a len()
função global, a mesma que usamos para obter o comprimento de uma string:
len(items) #4
Você pode adicionar itens à lista usando um append()
método de lista:
items.append("Test")
ou o método extend():
items.extend(["Test"])
Você também pode usar o +=
operador:
items += ["Test"]
# items is ['Roger', 1, 'Syd', True, 'Test']
Dica: com
extend()
ou+=
não se esqueça dos colchetes. Não useitems += "Test"
ouitems.extend("Test")
ou Python adicionará 4 caracteres individuais à lista, resultando em['Roger', 1, 'Syd', True, 'T', 'e', 's', 't']
Remova um item usando o remove()
método:
items.remove("Test")
Você pode adicionar vários elementos usando
items += ["Test1", "Test2"]
#or
items.extend(["Test1", "Test2"])
Eles acrescentam o item ao final da lista.
Para adicionar um item no meio de uma lista, em um índice específico, use o insert()
método:
items.insert("Test", 1) # add "Test" at index 1
Para adicionar vários itens em um índice específico, você precisa usar fatias:
items[1:1] = ["Test1", "Test2"]
Classifique uma lista usando o sort()
método:
items.sort()
Dica: sort() só funcionará se a lista contiver valores que possam ser comparados. Strings e inteiros, por exemplo, não podem ser comparados, e você receberá um erro como
TypeError: '<' not supported between instances of 'int' and 'str'
se tentasse.
Os sort()
métodos ordenam primeiro as letras maiúsculas e depois as minúsculas. Para corrigir isso, use:
items.sort(key=str.lower)
em vez de.
A classificação modifica o conteúdo original da lista. Para evitar isso, você pode copiar o conteúdo da lista usando
itemscopy = items[:]
ou use a sorted()
função global:
print(sorted(items, key=str.lower))
que retornará uma nova lista, ordenada, em vez de modificar a lista original.
Duplos em Python
Tuplas são outra estrutura de dados fundamental do Python.
Elas permitem criar grupos imutáveis de objetos. Isso significa que, uma vez criada uma tupla, ela não pode ser modificada. Você não pode adicionar ou remover itens.
Elas são criadas de maneira semelhante às listas, mas usando parênteses em vez de colchetes:
names = ("Roger", "Syd")
Uma tupla é ordenada, como uma lista, então você pode obter seus valores referenciando um valor de índice:
names[0] # "Roger"
names[1] # "Syd"
Você também pode usar o index()
método:
names.index('Roger') # 0
names.index('Syd') # 1
Assim como acontece com strings e listas, usar um índice negativo iniciará a pesquisa do final:
names[-1] # True
Você pode contar os itens em uma tupla com a len()
função:
len(names) # 2
Você pode verificar se um item está contido em uma tupla com o in
operador:
print("Roger" in names) # True
Você também pode extrair uma parte de uma tupla usando fatias:
names[0:2] # ('Roger', 'Syd')
names[1:] # ('Syd',)
Obtenha o número de itens em uma tupla usando a len()
função global, a mesma que usamos para obter o comprimento de uma string:
len(names) #2
Você pode criar uma versão ordenada de uma tupla usando a sorted()
função global:
sorted(names)
Você pode criar uma nova tupla a partir de tuplas existentes usando o +
operador:
newTuple = names + ("Vanille", "Tina")
Dicionários em Python
Dicionários são uma estrutura de dados muito importante do Python.
Enquanto as listas permitem que você crie coleções de valores, os dicionários permitem que você crie coleções de pares chave/valor .
Aqui está um exemplo de dicionário com um par chave/valor:
dog = { 'name': 'Roger' }
A chave pode ser qualquer valor imutável, como uma string, um número ou uma tupla. O valor pode ser o que você quiser.
Um dicionário pode conter vários pares chave/valor:
dog = { 'name': 'Roger', 'age': 8 }
Você pode acessar valores de chaves individuais usando esta notação:
dog['name'] # 'Roger'
dog['age'] # 8
Usando a mesma notação, você pode alterar o valor armazenado em um índice específico:
dog['name'] = 'Syd'
E outra maneira é usar o get()
método, que tem uma opção para adicionar um valor padrão:
dog.get('name') # 'Roger'
dog.get('test', 'default') # 'default'
O pop()
método recupera o valor de uma chave e, posteriormente, exclui o item do dicionário:
dog.pop('name') # 'Roger'
O popitem()
método recupera e remove o último par chave/valor inserido no dicionário:
dog.popitem()
Você pode verificar se uma chave está contida em um dicionário com o in
operador:
'name' in dog # True
Obtenha uma lista com as chaves em um dicionário usando o keys()
método, passando seu resultado para o list()
construtor:
list(dog.keys()) # ['name', 'age']
Obtenha os valores usando o values()
método e as tuplas de pares chave/valor usando o items()
método:
print(list(dog.values()))
# ['Roger', 8]
print(list(dog.items()))
# [('name', 'Roger'), ('age', 8)]
Obtenha o comprimento de um dicionário usando a len()
função global, a mesma que usamos para obter o comprimento de uma string ou dos itens em uma lista:
len(dog) #2
Você pode adicionar um novo par chave/valor ao dicionário desta maneira:
dog['favorite food'] = 'Meat'
Você pode remover um par chave/valor de um dicionário usando a del
instrução:
del dog['favorite food']
Para copiar um dicionário, use o método copy():
dogCopy = dog.copy()
Conjuntos em Python
Conjuntos são outra estrutura de dados importante do Python.
Podemos dizer que elas funcionam como tuplas, mas não são ordenadas e são mutáveis .
Ou podemos dizer que eles funcionam como dicionários, mas não têm chaves.
Eles também têm uma versão imutável, chamada frozenset
.
Você pode criar um conjunto usando esta sintaxe:
names = {"Roger", "Syd"}
Os conjuntos funcionam bem quando você pensa neles como conjuntos matemáticos.
Você pode cruzar dois conjuntos:
set1 = {"Roger", "Syd"}
set2 = {"Roger"}
intersect = set1 & set2 #{'Roger'}
Você pode criar uma união de dois conjuntos:
set1 = {"Roger", "Syd"}
set2 = {"Luna"}
union = set1 | set2
#{'Syd', 'Luna', 'Roger'}
Você pode obter a diferença entre dois conjuntos:
set1 = {"Roger", "Syd"}
set2 = {"Roger"}
difference = set1 - set2 #{'Syd'}
Você pode verificar se um conjunto é um superconjunto de outro (e, claro, se um conjunto é um subconjunto de outro):
set1 = {"Roger", "Syd"}
set2 = {"Roger"}
isSuperset = set1 > set2 # True
Você pode contar os itens em um conjunto com a len()
função global:
names = {"Roger", "Syd"}
len(names) # 2
Você pode obter uma lista dos itens em um conjunto passando o conjunto para o list()
construtor:
names = {"Roger", "Syd"}
list(names) #['Syd', 'Roger']
Você pode verificar se um item está contido em um conjunto com o in
operador:
print("Roger" in names) # True
Funções em Python
Uma função nos permite criar um conjunto de instruções que podemos executar quando necessário.
Funções são essenciais em Python e em muitas outras linguagens de programação. Elas nos ajudam a criar programas significativos, pois nos permitem decompor um programa em partes gerenciáveis e promovem a legibilidade e a reutilização do código.
Aqui está um exemplo de função hello
que imprime "Olá!":
def hello():
print('Hello!')
Esta é a definição da função . Há um nome ( hello
) and a body, the set of instructions, which is the part that follows the colon. It's indented one level on the right.
Para executar esta função, precisamos chamá-la. Esta é a sintaxe para chamar a função:
hello()
Podemos executar esta função uma ou várias vezes.
O nome da função, hello
, é muito importante. Deve ser descritivo, para que qualquer pessoa que o chame possa imaginar o que a função faz.
Uma função pode aceitar um ou mais parâmetros:
def hello(name):
print('Hello ' + name + '!')
Neste caso chamamos a função passando o argumento
hello('Roger')
Chamamos de parâmetros os valores aceitos pela função dentro da definição da função, e de argumentos os valores que passamos para a função quando a chamamos. É comum ficar confuso com essa distinção.
Um argumento pode ter um valor padrão que é aplicado se o argumento não for especificado:
def hello(name='my friend'):
print('Hello ' + name + '!')
hello()
#Hello my friend!
Veja como podemos aceitar vários parâmetros:
def hello(name, age):
print('Hello ' + name + ', you are ' + str(age) + ' years old!')
Neste caso chamamos a função passando um conjunto de argumentos:
hello('Roger', 8)
Parâmetros são passados por referência. Todos os tipos em Python são objetos, mas alguns deles são imutáveis, incluindo inteiros, booleanos, floats, strings e tuplas. Isso significa que, se você os passar como parâmetros e modificar seus valores dentro da função, o novo valor não será refletido fora da função:
def change(value):
value = 2
val = 1
change(val)
print(val) #1
Se você passar um objeto que não é imutável e alterar uma de suas propriedades, a alteração será refletida externamente.
Uma função pode retornar um valor usando a return
instrução. Por exemplo, neste caso, retornamos o name
nome do parâmetro:
def hello(name):
print('Hello ' + name + '!')
return name
Quando a função atende à return
instrução, a função termina.
Podemos omitir o valor:
def hello(name):
print('Hello ' + name + '!')
return
Podemos ter a instrução return dentro de uma condicional, que é uma maneira comum de encerrar uma função se uma condição inicial não for atendida:
def hello(name):
if not name:
return
print('Hello ' + name + '!')
Se chamarmos a função passando um valor que é avaliado como False
, como uma string vazia, a função será encerrada antes de chegar à print()
instrução.
Você pode retornar vários valores usando valores separados por vírgula:
def hello(name):
print('Hello ' + name + '!')
return name, 'Roger', 8
Neste caso, a chamada hello('Syd')
do valor de retorno é uma tupla contendo esses 3 valores: ('Syd', 'Roger', 8)
.
Objetos em Python
Tudo em Python é um objeto.
Até mesmo valores de tipos primitivos básicos (inteiro, string, float...) são objetos. Listas são objetos, assim como tuplas, dicionários, tudo.
Objetos têm atributos e métodos que podem ser acessados usando a sintaxe de ponto.
Por exemplo, tente definir uma nova variável do tipo int
:
age = 8
age
agora tem acesso às propriedades e métodos definidos para todos int
os objetos.
Isso inclui, por exemplo, o acesso à parte real e imaginária desse número:
print(age.real) # 8
print(age.imag) # 0
print(age.bit_length()) #4
# the bit_length() method returns the number of bits necessary to represent this number in binary notation
Uma variável que contém um valor de lista tem acesso a um conjunto diferente de métodos:
items = [1, 2]
items.append(3)
items.pop()
Os métodos dependem do tipo de valor.
A id()
função global fornecida pelo Python permite que você inspecione a localização na memória de um objeto específico.
id(age) # 140170065725376
O valor da sua memória mudará. Estou mostrando isso apenas como um exemplo.
Se você atribuir um valor diferente à variável, seu endereço mudará, porque o conteúdo da variável foi substituído por outro valor armazenado em outro local na memória:
age = 8
print(id(age)) # 140535918671808
age = 9
print(id(age)) # 140535918671840
Mas se você modificar o objeto usando seus métodos, o endereço permanece o mesmo:
items = [1, 2]
print(id(items)) # 140093713593920
items.append(3)
print(items) # [1, 2, 3]
print(id(items)) # 140093713593920
O endereço só muda se você reatribuir uma variável a outro valor.
Alguns objetos são mutáveis , enquanto outros são imutáveis . Isso depende do próprio objeto.
Se o objeto fornece métodos para alterar seu conteúdo, ele é mutável. Caso contrário, é imutável.
A maioria dos tipos definidos pelo Python são imutáveis. Por exemplo, an int
é imutável. Não há métodos para alterar seu valor. Se você incrementar o valor usando
age = 8
age = age + 1
#or
age += 1
e você verificar com id(age)
, verá que age
aponta para um local de memória diferente. O valor original não sofreu mutação, apenas mudamos para outro valor.
Laços em Python
Os loops são uma parte essencial da programação.
Em Python, temos dois tipos de loops: loops while e loops for .
while
laços em Python
while
Os loops são definidos usando a while
palavra-chave e repetem seu bloco até que a condição seja avaliada como False
:
condition = True
while condition == True:
print("The condition is True")
Este é um loop infinito . Ele nunca acaba.
Vamos parar o loop logo após a primeira iteração:
condition = True
while condition == True:
print("The condition is True")
condition = False
print("After the loop")
Neste caso, a primeira iteração é executada, pois o teste de condição é avaliado como True
. Na segunda iteração, o teste de condição é avaliado como False
, então o controle avança para a próxima instrução após o loop.
É comum ter um contador para interromper a iteração após um certo número de ciclos:
count = 0
while count < 10:
print("The condition is True")
count = count + 1
print("After the loop")
for
laços em Python
Usando for
loops, podemos dizer ao Python para executar um bloco por um número pré-determinado de vezes, de antemão, e sem a necessidade de uma variável separada e condicional para verificar seu valor.
Por exemplo, podemos iterar os itens em uma lista:
items = [1, 2, 3, 4]
for item in items:
print(item)
Ou você pode iterar um número específico de vezes usando a range()
função:
for item in range(04):
print(item)
range(4)
cria uma sequência que começa em 0 e contém 4 itens: [0, 1, 2, 3]
.
Para obter o índice, você deve encapsular a sequência na enumerate()
função:
items = [1, 2, 3, 4]
for index, item in enumerate(items):
print(index, item)
Interromper e continuar em Python
Ambos os loops while
e for
podem ser interrompidos dentro do bloco, usando duas palavras-chave especiais: break
e continue
.
continue
interrompe a iteração atual e diz ao Python para executar a próxima.
break
interrompe o loop completamente e continua com a próxima instrução após o término do loop.
O primeiro exemplo aqui imprime 1, 3, 4
. O segundo exemplo imprime 1
:
items = [1, 2, 3, 4]
for item in items:
if item == 2:
continue
print(item)
items = [1, 2, 3, 4]
for item in items:
if item == 2:
break
print(item)
Aulas em Python
Além de usar os tipos fornecidos pelo Python, podemos declarar nossas próprias classes e, a partir delas, podemos instanciar objetos.
Um objeto é uma instância de uma classe. Uma classe é o tipo de um objeto.
Podemos definir uma classe desta forma:
class <class_name>:
# my class
Por exemplo, vamos definir uma classe Dog
class Dog:
# the Dog class
Uma classe pode definir métodos:
class Dog:
# the Dog class
def bark(self):
print('WOF!')
self
como o argumento do método aponta para a instância do objeto atual e deve ser especificado ao definir um método.
Criamos uma instância de uma classe, um objeto , usando esta sintaxe:
roger = Dog()
Agora roger
é um novo objeto do tipo Cachorro.
Se você correr
print(type(roger))
Você vai conseguir <class '__main__.Dog'>
Um tipo especial de método __init__()
é chamado construtor, e podemos usá-lo para inicializar uma ou mais propriedades quando criamos um novo objeto dessa classe:
class Dog:
# the Dog class
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
print('WOF!')
Nós o usamos desta maneira:
roger = Dog('Roger', 8)
print(roger.name) # 'Roger'
print(roger.age) # 8
roger.bark() # 'WOF!'
Uma característica importante das classes é a herança.
Podemos criar uma classe Animal com um método walk()
:
class Animal:
def walk(self):
print('Walking..')
e a classe Dog pode herdar de Animal:
class Dog(Animal):
def bark(self):
print('WOF!')
Agora, criar um novo objeto de classe Dog
terá o walk()
método herdado de Animal
:
roger = Dog()
roger.walk() # 'Walking..'
roger.bark() # 'WOF!'
Módulos em Python
Cada arquivo Python é um módulo.
Você pode importar um módulo de outros arquivos, e essa é a base de qualquer programa de complexidade moderada, pois promove uma organização sensata e reutilização de código.
Em um programa Python típico, um arquivo atua como ponto de entrada. Os outros arquivos são módulos e expõem funções que podemos chamar de outros arquivos.
O arquivo dog.py
contém este código:
def bark():
print('WOF!')
Podemos importar esta função de outro arquivo usando import
. E, uma vez feito isso, podemos referenciá-la usando a notação de ponto, dog.bark()
:
import dog
dog.bark()
Ou podemos usar a from .. import
sintaxe e chamar a função diretamente:
from dog import bark
bark()
A primeira estratégia nos permite carregar tudo o que está definido em um arquivo.
A segunda estratégia nos permite escolher as coisas que precisamos.
Esses módulos são específicos para o seu programa e a importação depende do arquivo no sistema de arquivos.
Suponha que você coloque dog.py
em uma lib
subpasta.
Nessa pasta, você precisa criar um arquivo vazio chamado __init__.py
. Isso informa ao Python que a pasta contém módulos.
Agora você pode escolher - você pode importar dog
de lib
:
from lib import dog
dog.bark()
ou você pode referenciar a dog
função específica do módulo importando de lib.dog
:
from lib.dog import bark
bark()
A Biblioteca Padrão do Python
O Python expõe muitas funcionalidades integradas por meio de sua biblioteca padrão .
A biblioteca padrão é uma coleção enorme de todos os tipos de utilitários, desde utilitários matemáticos até depuração e criação de interfaces gráficas de usuário.
Você pode encontrar a lista completa de módulos da biblioteca padrão aqui: https://docs.python.org/3/library/index.html
Alguns dos módulos importantes são:
math
para utilitários matemáticosre
para expressões regularesjson
para trabalhar com JSONdatetime
trabalhar com datassqlite3
usar SQLiteos
para utilitários do sistema operacionalrandom
para geração de números aleatóriosstatistics
para utilitários de estatísticasrequests
para executar solicitações de rede HTTPhttp
para criar servidores HTTPurllib
para gerenciar URLs
Vamos apresentar como usar um módulo da biblioteca padrão. Você já sabe como usar os módulos que cria, importando-os de outros arquivos na pasta do programa.
Bem, o mesmo acontece com os módulos fornecidos pela biblioteca padrão:
import math
math.sqrt(4) # 2.0
ou
from math import sqrt
sqrt(4) # 2.0
Em breve, exploraremos os módulos mais importantes individualmente para entender o que podemos fazer com eles.
Guia de Estilo Python PEP8
Ao escrever código, você deve seguir as convenções da linguagem de programação que usa.
Se você aprender as convenções corretas de nomenclatura e formatação desde o início, será mais fácil ler o código escrito por outras pessoas, e as pessoas acharão o seu código mais fácil de ler.
O Python define suas convenções no guia de estilo PEP8. PEP significa Propostas de Melhoria do Python e é o local onde acontecem todas as discussões e melhorias da linguagem Python.
Há muitas propostas de PEP, todas disponíveis em https://www.python.org/dev/peps/.
O PEP8 é um dos primeiros, e também um dos mais importantes. Ele define a formatação e também algumas regras sobre como escrever Python de forma "pythônica".
Você pode ler o conteúdo completo aqui: https://www.python.org/dev/peps/pep-0008/, mas aqui está um rápido resumo dos pontos importantes com os quais você pode começar:
- Recuo usando espaços, não tabulações
- Recuo usando 4 espaços.
- Os arquivos Python são codificados em UTF-8
- Use no máximo 80 colunas para seu código
- Escreva cada afirmação em sua própria linha
- Funções, nomes de variáveis e nomes de arquivos são escritos em letras minúsculas, com sublinhados entre as palavras (snake_case)
- Os nomes das classes são escritos em maiúsculas, palavras separadas também são escritas com letras maiúsculas (CamelCase)
- Os nomes dos pacotes são minúsculos e não possuem sublinhados entre as palavras
- Variáveis que não devem mudar (constantes) são escritas em letras maiúsculas
- Os nomes das variáveis devem ser significativos
- Adicione comentários úteis, mas evite comentários óbvios
- Adicionar espaços ao redor dos operadores
- Não use espaços em branco desnecessários
- Adicione uma linha em branco antes de uma função
- Adicione uma linha em branco entre os métodos em uma classe
- Dentro de funções/métodos, linhas em branco podem ser usadas para separar blocos de código relacionados para ajudar na legibilidade
Depuração em Python
A depuração é uma das melhores habilidades que você pode aprender, pois ela o ajudará em muitas situações difíceis.
Cada linguagem tem seu depurador. Python tem o pdb
, disponível na biblioteca padrão.
Você depura adicionando um ponto de interrupção ao seu código:
breakpoint()
Você pode adicionar mais pontos de interrupção, se necessário.
Quando o interpretador Python atinge um ponto de interrupção no seu código, ele para e informa qual é a próxima instrução a ser executada.
Então você pode fazer algumas coisas.
Você pode digitar o nome de qualquer variável para inspecionar seu valor.
Você pode pressionar n
para avançar para a próxima linha na função atual. Se o código chamar funções, o depurador não as acessará e as considerará "caixas pretas".
Você pode pressionar s
para avançar para a próxima linha na função atual. Se a próxima linha for uma função, o depurador entra nela, e você pode executar uma instrução dessa função por vez.
Você pode pressionar c
para continuar a execução do programa normalmente, sem a necessidade de fazê-lo passo a passo.
Você pode pressionar q
para interromper a execução do programa.
A depuração é útil para avaliar o resultado de uma instrução e é especialmente bom saber como usá-la quando você tem iterações ou algoritmos complexos que deseja corrigir.
Escopo de Variáveis em Python
Quando você declara uma variável, ela fica visível em partes do seu programa, dependendo de onde você a declara.
Se você declará-la fora de qualquer função, a variável ficará visível para qualquer código executado após a declaração, incluindo funções:
age = 8
def test():
print(age)
print(age) # 8
test() # 8
Nós chamamos isso de variável global .
Se você definir uma variável dentro de uma função, essa variável será uma variável local e só será visível dentro dessa função. Fora da função, ela não será acessível:
def test():
age = 8
print(age)
test() # 8
print(age)
# NameError: name 'age' is not defined
Como aceitar argumentos da linha de comando em Python
O Python oferece várias maneiras de lidar com argumentos passados quando invocamos o programa a partir da linha de comando.
Até agora você executou programas de um REPL ou usando
python <filename>.py
Você pode passar argumentos e opções adicionais quando fizer isso, assim:
python <filename>.py <argument1>
python <filename>.py <argument1> <argument2>
Uma maneira básica de lidar com esses argumentos é usar o sys
módulo da biblioteca padrão.
Você pode obter os argumentos passados na sys.argv
lista:
import sys
print(len(sys.argv))
print(sys.argv)
UM sys.argv
lista contém como primeiro item o nome do arquivo que foi executado, por exemplo ['main.py']
.
Esta é uma maneira simples, mas exige bastante trabalho. É preciso validar os argumentos, garantir que o tipo deles esteja correto e enviar um feedback ao usuário caso ele não esteja usando o programa corretamente.
O Python fornece outro pacote na biblioteca padrão para ajudar você: argparse
.
Primeiro você importa argparse
e chama argparse.ArgumentParser()
, passando a descrição do seu programa:
import argparse
parser = argparse.ArgumentParser(
description='This program prints the name of my dogs'
)
Em seguida, você adiciona os argumentos que deseja aceitar. Por exemplo, neste programa, aceitamos uma -c
opção para passar uma cor, assim:python program.py -c red
import argparse
parser = argparse.ArgumentParser(
description='This program prints a color HEX value'
)
parser.add_argument('-c', '--color', metavar='color', required=True, help='the color to search for')
args = parser.parse_args()
print(args.color) # 'red'
Se o argumento não for especificado, o programa gerará um erro:
➜ python python program.py
usage: program.py [-h] -c color
program.py: error: the following arguments are required: -c
Você pode definir uma opção para ter um conjunto específico de valores, usando choices
:
parser.add_argument('-c', '--color', metavar='color', required=True, choices={'red','yellow'}, help='the color to search for')
➜ python python program.py -c blue
usage: program.py [-h] -c color
program.py: error: argument -c/--color: invalid choice: 'blue' (choose from 'yellow', 'red')
Há mais opções, mas essas são as básicas.
E há pacotes comunitários que também fornecem essa funcionalidade, como o Click e o Python Prompt Toolkit .
Funções Lambda em Python
Funções lambda (também chamadas de funções anônimas) são funções pequenas que não têm nome e têm apenas uma expressão como corpo.
Em Python, eles são definidos usando a lambda
palavra-chave:
lambda <arguments> : <expression>
O corpo deve ser uma única expressão — uma expressão, não uma declaração.
Essa diferença é importante. Uma expressão retorna um valor, uma instrução não.
O exemplo mais simples de função lambda é uma função que dobra o valor de um número:
lambda num : num * 2
As funções lambda podem aceitar mais argumentos:
lambda a, b : a * b
As funções lambda não podem ser invocadas diretamente, mas você pode atribuí-las a variáveis:
multiply = lambda a, b : a * b
print(multiply(2, 2)) # 4
A utilidade das funções lambda surge quando combinadas com outros recursos do Python, por exemplo, em combinação com map()
, filter()
e reduce()
.
Recursão em Python
Uma função em Python pode chamar a si mesma. É isso que é recursão. E pode ser muito útil em muitos cenários.
A maneira comum de explicar a recursão é usando o cálculo fatorial.
O fatorial de um número é o número n
multiplicado por n-1
, multiplicado por n-2
... e assim por diante, até chegar ao número 1
:
3! = 3 * 2 * 1 = 6
4! = 4 * 3 * 2 * 1 = 24
5! = 5 * 4 * 3 * 2 * 1 = 120
Usando recursão, podemos escrever uma função que calcula o fatorial de qualquer número:
def factorial(n):
if n == 1: return 1
return n * factorial(n-1)
print(factorial(3)) # 6
print(factorial(4)) # 24
print(factorial(5)) # 120
factorial()
Se você chamar a função factorial(n)
em vez de factorial(n-1)
, causará uma recursão infinita. Por padrão, o Python interrompe as recursões em 1.000 chamadas e, quando esse limite for atingido, ocorrerá um RecursionError
erro.
A recursão é útil em muitos lugares e nos ajuda a simplificar nosso código quando não há outra maneira ideal de fazê-lo, então é bom conhecer essa técnica.
Funções aninhadas em Python
Funções em Python podem ser aninhadas dentro de outras funções.
Uma função definida dentro de uma função é visível somente dentro dessa função.
Isso é útil para criar utilitários que são úteis para uma função, mas não úteis fora dela.
Você pode perguntar: por que eu deveria "esconder" essa função, se ela não causa danos?
Primeiro, porque é sempre melhor ocultar a funcionalidade que é local para uma função e não é útil em outro lugar.
Também porque podemos fazer uso de fechamentos (mais sobre isso depois).
Aqui está um exemplo:
def talk(phrase):
def say(word):
print(word)
words = phrase.split(' ')
for word in words:
say(word)
talk('I am going to buy the milk')
Se você quiser acessar uma variável definida na função externa a partir da função interna, primeiro você precisa declará-la como nonlocal
:
def count():
count = 0
def increment():
nonlocal count
count = count + 1
print(count)
increment()
count()
Isso é útil especialmente com fechamentos, como veremos a seguir.
Fechamentos em Python
Se você retornar uma função aninhada de uma função, essa função aninhada terá acesso às variáveis definidas nessa função, mesmo que ela não esteja mais ativa.
Aqui está um contra-exemplo simples.
def counter():
count = 0
def increment():
nonlocal count
count = count + 1
return count
return increment
increment = counter()
print(increment()) # 1
print(increment()) # 2
print(increment()) # 3
Retornamos a increment()
função interna, e ela ainda tem acesso ao estado da count
variável, mesmo que a counter()
função tenha terminado.
Decoradores em Python
Decoradores são uma maneira de mudar, aprimorar ou alterar de alguma forma o funcionamento de uma função.
Os decoradores são definidos com o @
símbolo seguido do nome do decorador, logo antes da definição da função.
Exemplo:
@logtime
def hello():
print('hello!')
Esta hello
função tem a logtime
decorador atribuído.
Sempre que ligamos hello()
, o decorador será chamado.
Um decorador é uma função que recebe uma função como parâmetro, encapsula a função em uma função interna que executa a tarefa que ela precisa realizar e retorna essa função interna. Em outras palavras:
def logtime(func):
def wrapper():
# do something before
val = func()
# do something after
return val
return wrapper
Docstrings em Python
A documentação é extremamente importante, não apenas para comunicar a outras pessoas qual é o objetivo de uma função/classe/método/módulo, mas também para comunicá-lo a você mesmo.
Quando você retornar ao seu código daqui a 6 ou 12 meses, talvez não se lembre de todo o conhecimento que tem na cabeça. Nesse momento, ler seu código e entender o que ele deve fazer será muito mais difícil.
Os comentários são uma maneira de ajudar você (e os outros):
# this is a comment
num = 1 #this is another comment
Outra maneira é usar docstrings .
A utilidade das docstrings é que elas seguem convenções. Como tal, podem ser processadas automaticamente.
É assim que você define uma docstring para uma função:
def increment(n):
"""Increment a number"""
return n + 1
É assim que você define uma docstring para uma classe e um método:
class Dog:
"""A class representing a dog"""
def __init__(self, name, age):
"""Initialize a new dog"""
self.name = name
self.age = age
def bark(self):
"""Let the dog bark"""
print('WOF!')
Documente um módulo colocando uma docstring no topo do arquivo, por exemplo, supondo que isto seja dog.py
:
"""Dog module
This module does ... bla bla bla and provides the following classes:
- Dog
...
"""
class Dog:
"""A class representing a dog"""
def __init__(self, name, age):
"""Initialize a new dog"""
self.name = name
self.age = age
def bark(self):
"""Let the dog bark"""
print('WOF!')
Docstrings podem abranger várias linhas:
def increment(n):
"""Increment
a number
"""
return n + 1
O Python processará essas informações e você poderá usar a help()
função global para obter a documentação de uma classe/método/função/módulo.
Por exemplo, ligar help(increment)
lhe dará isto:
Help on function increment in module
__main__:
increment(n)
Increment
a number
Existem muitos padrões diferentes para formatar docstrings, e você pode escolher seguir o seu favorito.
Gosto do padrão do Google: https://github.com/google/styleguide/blob/gh-pages/pyguide.md#38-comments-and-docstrings
Os padrões permitem ter ferramentas para extrair docstrings e gerar automaticamente documentação para seu código.
Introspecção em Python
Funções, variáveis e objetos podem ser analisados usando introspecção .
Primeiro, usando a help()
função global, podemos obter a documentação, se fornecida em forma de docstrings.
Então, você pode usar print() para obter informações sobre uma função:
def increment(n):
return n + 1
print(increment)
# <function increment at 0x7f420e2973a0>
ou um objeto:
class Dog():
def bark(self):
print('WOF!')
roger = Dog()
print(roger)
# <__main__.Dog object at 0x7f42099d3340>
A type()
função nos dá o tipo de um objeto:
print(type(increment))
# <class 'function'>
print(type(roger))
# <class '__main__.Dog'>
print(type(1))
# <class 'int'>
print(type('test'))
# <class 'str'>
A dir()
função global nos permite descobrir todos os métodos e atributos de um objeto:
print(dir(roger))
# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bark']
A id()
função global nos mostra a localização na memória de qualquer objeto:
print(id(roger)) # 140227518093024
print(id(1)) # 140227521172384
Pode ser útil verificar se duas variáveis apontam para o mesmo objeto.
O inspect
módulo da biblioteca padrão nos fornece mais ferramentas para obter informações sobre objetos, e você pode conferir aqui: https://docs.python.org/3/library/inspect.html
Anotações em Python
Python é tipado dinamicamente. Não precisamos especificar o tipo de uma variável ou parâmetro de função, nem o valor de retorno de uma função.
As anotações nos permitem (opcionalmente) fazer isso.
Esta é uma função sem anotações:
def increment(n):
return n + 1
Esta é a mesma função com anotações:
def increment(n: int) -> int:
return n + 1
Você também pode anotar variáveis:
count: int = 0
O Python ignorará essas anotações. Uma ferramenta separada chamada mypy
pode ser executada de forma independente ou integrada por uma IDE como o VS Code ou o PyCharm para verificar automaticamente se há erros de tipo estaticamente enquanto você codifica. Ela também ajudará você a detectar erros de incompatibilidade de tipo antes mesmo de executar o código.
Uma grande ajuda, especialmente quando seu software fica grande e você precisa refatorar seu código.
Exceções em Python
É importante ter uma maneira de lidar com erros, e o Python nos fornece tratamento de exceções para fazer isso.
Se você encapsular linhas de código em um try:
bloco:
try:
# some lines of code
Se ocorrer um erro, o Python irá alertá-lo e você poderá determinar que tipo de erro ocorreu usando um except
bloco:
try:
# some lines of code
except <ERROR1>:
# handler <ERROR1>
except <ERROR2>:
# handler <ERROR2>
Para capturar todas as exceções, você pode usar except
sem nenhum tipo de erro:
try:
# some lines of code
except <ERROR1>:
# handler <ERROR1>
except:
# catch all other exceptions
O else
bloco é executado se nenhuma exceção for encontrada:
try:
# some lines of code
except <ERROR1>:
# handler <ERROR1>
except <ERROR2>:
# handler <ERROR2>
else:
# no exceptions were raised, the code ran successfully
Um finally
bloco permite que você execute alguma operação em qualquer caso, independentemente de ter ocorrido um erro ou não:
try:
# some lines of code
except <ERROR1>:
# handler <ERROR1>
except <ERROR2>:
# handler <ERROR2>
else:
# no exceptions were raised, the code ran successfully
finally:
# do something in any case
O erro específico que ocorrerá depende da operação que você está realizando.
Por exemplo, se você estiver lendo um arquivo, poderá obter um EOFError
. Se você dividir um número por zero, obterá um ZeroDivisionError
. Se você tiver um problema de conversão de tipo, poderá obter um TypeError
.
Experimente este código:
result = 2 / 0
print(result)
O programa será encerrado com um erro:
Traceback (most recent call last):
File "main.py", line 1, in <module>
result = 2 / 0
ZeroDivisionError: division by zero
e as linhas de código após o erro não serão executadas.
Adicionar essa operação em um try:
bloco nos permite recuperar graciosamente e prosseguir com o programa:
try:
result = 2 / 0
except ZeroDivisionError:
print('Cannot divide by zero!')
finally:
result = 1
print(result) # 1
Você também pode gerar exceções em seu próprio código usando a raise
instrução:
raise Exception('An error occurred!')
Isso gera uma exceção geral, e você pode interceptá-la usando:
try:
raise Exception('An error occurred!')
except Exception as error:
print(error)
Você também pode definir sua própria classe de exceção, estendendo-se de Exception:
class DogNotFoundException(Exception):
pass
pass
aqui significa "nada" e devemos usá-lo quando definimos uma classe sem métodos, ou uma função sem código também.
try:
raise DogNotFoundException()
except DogNotFoundException:
print('Dog not found!')
UM with
declaração em Python
UM with
declaração é muito útil para simplificar o trabalho com tratamento de exceções.
Por exemplo, ao trabalhar com arquivos, cada vez que abrimos um arquivo, devemos lembrar de fechá-lo.
with
torna esse processo transparente.
Em vez de escrever:
filename = '/Users/flavio/test.txt'
try:
file = open(filename, 'r')
content = file.read()
print(content)
finally:
file.close()
Você pode escrever:
filename = '/Users/flavio/test.txt'
with open(filename, 'r') as file:
content = file.read()
print(content)
Em outras palavras, temos um tratamento de exceção implícito integrado, que close()
será chamado automaticamente para nós.
with
não é útil apenas para trabalhar com arquivos. O exemplo acima serve apenas para apresentar seus recursos.
Como instalar pacotes de terceiros em Python usandopip
A biblioteca padrão do Python contém um grande número de utilitários que simplificam nossas necessidades de desenvolvimento em Python, mas nada pode satisfazer tudo .
É por isso que indivíduos e empresas criam pacotes e os disponibilizam como software de código aberto para toda a comunidade.
Todos esses módulos são reunidos em um único lugar, o Índice de Pacotes Python, disponível em https://pypi.org, e podem ser instalados no seu sistema usando pip
.
Há mais de 270.000 pacotes disponíveis gratuitamente no momento em que este artigo foi escrito.
Você
pip
já deve ter instalado se seguiu as instruções de instalação do Python.
Instale qualquer pacote usando o comando pip install
:
pip install <package>
ou, se você tiver problemas, você também pode executá-lo através de python -m
:
python -m pip install <package>
Por exemplo, você pode instalar o requests
pacote, uma biblioteca HTTP popular:
pip install requests
e quando fizer isso, ele estará disponível para todos os seus scripts Python, porque os pacotes são instalados globalmente.
A localização exata depende do seu sistema operacional.
No macOS, executando Python 3.9, o local é /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages
.
Atualize um pacote para sua versão mais recente usando:
pip install –U <package>
Instale uma versão específica de um pacote usando:
pip install <package>==<version>
Desinstalar um pacote usando:
pip uninstall <package>
Exiba detalhes de um pacote instalado, incluindo versão, site de documentação e informações do autor usando:
pip show <package>
Compreensões de lista em Python
Compreensões de lista são uma maneira de criar listas de uma forma muito concisa.
Suponha que você tenha uma lista:
numbers = [1, 2, 3, 4, 5]
Você pode criar uma nova lista usando uma compreensão de lista, composta pelos numbers
elementos da lista, potência 2:
numbers_power_2 = [n**2 for n in numbers]
# [1, 4, 9, 16, 25]
Compreensões de lista são uma sintaxe que às vezes é preferida aos loops, pois é mais legível quando a operação pode ser escrita em uma única linha:
numbers_power_2 = []
for n in numbers:
numbers_power_2.append(n**2)
e mais map()
:
numbers_power_2 = list(map(lambda n : n**2, numbers))
Polimorfismo em Python
O polimorfismo generaliza uma funcionalidade para que ela funcione em diferentes tipos. É um conceito importante na programação orientada a objetos.
Podemos definir o mesmo método em classes diferentes:
class Dog:
def eat():
print('Eating dog food')
class Cat:
def eat():
print('Eating cat food')
Então podemos gerar objetos e chamar o eat()
método independentemente da classe à qual o objeto pertence, e obteremos resultados diferentes:
animal1 = Dog()
animal2 = Cat()
animal1.eat()
animal2.eat()
Construímos uma interface generalizada e agora não precisamos saber se um animal é um Gato ou um Cachorro.
Sobrecarga de operadores em Python
Sobrecarga de operadores é uma técnica avançada que podemos usar para tornar classes comparáveis e fazê-las funcionar com operadores Python.
Vamos dar uma olhada na aula do Cachorro:
class Dog:
# the Dog class
def __init__(self, name, age):
self.name = name
self.age = age
Vamos criar 2 objetos Dog:
roger = Dog('Roger', 8)
syd = Dog('Syd', 7)
Podemos usar sobrecarga de operadores para adicionar uma maneira de comparar esses dois objetos, com base na age
propriedade:
class Dog:
# the Dog class
def __init__(self, name, age):
self.name = name
self.age = age
def __gt__(self, other):
return True if self.age > other.age else False
Agora, se você tentar correr, print(roger > syd)
obterá o resultado True
.
Da mesma forma que definimos __gt__()
(que significa maior que), podemos definir os seguintes métodos:
__eq__()
para verificar a igualdade__lt__()
para verificar se um objeto deve ser considerado inferior a outro com o<
operador__le__()
para menor ou igual (<=
)__ge__()
para maior ou igual (>=
)__ne__()
para não igual (!=
)
Então você tem métodos para interoperar com operações aritméticas:
__add__()
responder ao+
operador__sub__()
responder ao–
operador__mul__()
responder ao*
operador__truediv__()
responder ao/
operador__floordiv__()
responder ao//
operador__mod__()
responder ao%
operador__pow__()
responder ao**
operador__rshift__()
responder ao>>
operador__lshift__()
responder ao<<
operador__and__()
responder ao&
operador__or__()
responder ao|
operador__xor__()
responder ao^
operador
Existem mais alguns métodos para trabalhar com outros operadores, mas você entendeu a ideia.
Ambientes virtuais em Python
É comum ter vários aplicativos Python em execução no seu sistema.
Quando os aplicativos exigem o mesmo módulo, em algum momento você chegará a uma situação complicada em que um aplicativo precisa de uma versão de um módulo, e outro aplicativo, de uma versão diferente do mesmo módulo.
Para resolver isso, você usa ambientes virtuais .
Usaremos venv
. Outras ferramentas funcionam de forma semelhante, como pipenv
.
Crie um ambiente virtual usando
python -m venv .venv
na pasta onde você deseja iniciar o projeto ou onde você já possui um projeto existente.
Então corra
source .venv/bin/activate
Uso
source .venv/bin/activate.fish
na concha do peixe
A execução do programa ativará o ambiente virtual Python. Dependendo da sua configuração, você também poderá ver o prompt do terminal mudar.
O meu mudou de
➜ folder
para
(.venv) ➜ folder
Agora, a execução pip
usará esse ambiente virtual em vez do ambiente global.
Conclusão
Muito obrigado por ler este livro.
Espero que isso inspire você a aprender mais sobre Python