print("Hello folks")
Nós vamos usar Python3
neste tutorial, pois é amplamente usado. A maioria das estruturas e bibliotecas suporta esta versão.
Nota: Qualquer versão acima do 3.5.2 suporta a maioria das bibliotecas e estruturas.
Índice:
- Introdução
- Instalação
- Shell Python
- Comente
- Impressão
- Indentação
- Variáveis
- Operadores
- Declarações condicionais
- Para Loops
- Enquanto loops
- Entrada do Usuário
- Typecasting
- Dicionários
- Listas
- Tuplas
- Conjuntos
- Funções e argumentos
- Args
- palavra-chave Argumentos
- Argumentos padrão
- kwargs
- Escopo
- Declaração de retorno
- Expressão Lambda
- Compreensão da lista
- Conceitos OOPS
- Aulas
- Métodos
- Objetos
- Construtor
- Atributo de instância
- Atributos de classe
- Auto
- Herança
- Super
- Herança múltipla
- Polimorfismo
- Encapsulamento
- Decoradores
- Exceções
- Importação de Pacotes
- Manipulação JSON
Nota: O tópico explicado no início é considerado para iniciantes. Se você tem experiência intermediária em python, pode pular para a parte de seu interesse.
Introdução:
De acordo com o Github’s octoverso, Python é a segunda linguagem mais usada pelos desenvolvedores em 2019.

Antes de aprender qualquer idioma, é mais útil saber como o idioma surgiu. Foi desenvolvido por Guido van Rossum, um programador holandês, e lançado em 1991.
Python é uma linguagem interpretada. Usa CPython Intérprete para compilar o código python em código de bytes. Para um iniciante, você não precisa saber muito sobre o CPython, mas deve estar ciente de como o python funciona internamente.
A filosofia por trás do python é que o código deve ser legível. Consegue isso com a ajuda do recuo. Ele suporta muitos paradigmas de programação, ou seja, funcional e orientado a objetos. Nós os entenderemos à medida que avançarmos no artigo.
A pergunta básica que o iniciante tem em mente é o que uma língua pode fazer. Aqui estão alguns dos casos de uso do python:
- Desenvolvimento do lado do servidor (Django, Flask)
- Ciência de dados (Pytorch, fluxo tensor)
- Análise / Visualização de dados (Matplotlib)
- Script (sopa bonita)
- Desenvolvimento incorporado
Nota: Não endosso nenhuma das bibliotecas ou estruturas mencionadas acima. Eles são populares e amplamente utilizados em seus respectivos domínios.
Instalação:
O primeiro passo para aprender qualquer linguagem de programação é saber como instalá-lo. Atualmente, o Python é incluído na maioria dos sistemas operacionais. Use o seguinte comando no seu terminal para verificar se o python está disponível:
python3 --version
Você verá a seguinte saída:
Python 3.7.0
Se você tem muitas versões disponíveis do python em seu sistema, poderá ver uma versão diferente. Se você possui o python instalado e a versão está acima da 3.5.2, você pode pular a seção. Para aqueles que não possuem o python instalado, siga as etapas abaixo:
Usuário do Windows:
- Vou ao Site oficial do Python.
- Clique no botão de download (Download Python 3.8.2)[[[[Nota: A versão pode diferir quando você está lendo este artigo]
- Vá para o caminho em que o pacote foi baixado e clique duas vezes no instalador.
- Marque a caixa indicando “Adicionar Python 3.x ao PATH” e clique em “Instalar agora”.
- Uma vez feito, você receberá um aviso dizendo “A instalação foi bem-sucedida”. Verifique novamente se o python está configurado corretamente usando o comando acima.
- Para confirmar se o python está instalado e configurado corretamente, use o comando
python3 --version
.
Usuário Mac:
- Primeiro instale o xcode da loja de aplicativos.
- Se você deseja instalar o Xcode usando o terminal, use o seguinte comando:
xcode-select --install
- Depois disso, para instalar o python, usaremos o gerenciador de pacotes brew. Para instalar e configurar preparar use o seguinte comando:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
- Depois que a configuração de preparação estiver concluída, use o seguinte comando para atualizar qualquer pacote desatualizado:
brew update
- Para instalar o python, use o seguinte comando:
brew install python3
- Para confirmar se o python está instalado e configurado corretamente, use o comando
python3 --version
.
Usuário Linux:
- Para instalar o python usando
apt
, use o seguinte comando:
sudo apt install python3
- Para instalar o python usando
yum
, use o seguinte comando:
sudo yum install python3
- Para confirmar se o python está instalado e configurado corretamente, use o comando
python3 --version
.
Shell Python:
É uma das ferramentas mais úteis que você encontrará. O shell python nos dá o poder de testar rapidamente qualquer conceito antes de integrá-lo ao nosso aplicativo.
Vá para o terminal ou prompt da linha de comando. Entrar python3
comando e você obterá a seguinte saída:
➜ python3.7
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 26 2018, 23:26:24)
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
Neste tutorial, aprenderemos alguns conceitos com a ajuda do python3 shell, que você pode ver acima. A partir de agora, sempre que eu mencionar vá para o shell python isso significa que você tem que usar python3
comando.
Enquanto para aprender os conceitos restantes, criaremos um arquivo com uma extensão .py
. Para executar este arquivo, usamos o seguinte comando:
python3 testing.py
Vamos para o shell python. Tipo 10 + 12
depois disto >>>
marca. Você obterá a saída 22:
>>> 10 + 12
22
Os comentários facilitam a escrita do código, pois ajudam a entender por que um determinado código é gravado. Outra coisa impressionante sobre o comentário é que ele ajuda a melhorar a legibilidade do código.
# Stay Safe
Quando você adiciona a seguinte sintaxe, o interpretador python entende que é um comentário. As linhas dentro disso não são executadas.
Você pode estar se perguntando por que usar comentários. Imagine que você é um desenvolvedor e foi designado para um tremendo projeto. O projeto possui mais de mil linhas de código. Agora, para entender como o código funciona, você precisará ir linha por linha e entendê-lo.
Qual a melhor solução para isso? Ahh! aqui vêm os comentários. Os comentários nos ajudam a entender por que um código específico é escrito e o que ele retorna ou faz. Considere isso como documentação para cada pedaço de código.
Impressão:
Acredite, além de ferramentas de depuração do editor, qualquer coisa que ajude o desenvolvedor a resolver o problema é uma declaração impressa. A impressão é uma das sintaxes subestimadas da programação e você descobrirá que será a mais útil ao depurar os problemas.
Então, como isso ajuda na depuração do problema? Bem, considere que você tem um módulo e deseja verificar o fluxo de execução para entendê-lo ou depurar um bug. Existem duas opções. Você pode usar um depurador ou adicionar uma declaração de impressão.
Nem sempre é possível definir um depurador. Por exemplo, se você estiver usando um shell python, um depurador não estará disponível. Nesse cenário, a impressão nos ajuda. Outro cenário é que, quando o aplicativo está sendo executado, você pode adicionar uma declaração de impressão que será exibida nos logs do seu aplicativo. Você pode monitorá-los em tempo de execução.
O Python fornece um método de impressão embutido com a seguinte sintaxe:
print("Stay safe...")
Recuo:
Outra parte interessante dessa linguagem é o recuo. Por quê? Bem, a resposta é simples: torna o código legível e bem formatado. É obrigatório em python seguir a regra do recuo. Se o recuo não for seguido, você receberá o seguinte erro:
IndentationError: unexpected indent
Veja até os erros em python são tão legíveis e fáceis de entender. No começo, você pode ficar aborrecido com a compulsão de indentação. Mas com o tempo você entenderá que o recuo é amigo do desenvolvedor.
Variáveis:
Como o nome indica, uma variável é algo que pode mudar. Uma variável é uma maneira de se referir a um local de memória usado por um programa de computador.
Bem, na maioria das linguagens de programação, você precisa atribuir o tipo a uma variável, mas em python, você não precisa. Por exemplo, na linguagem C para declarar um número inteiro, a seguinte sintaxe é usada int num = 5;
enquanto em python num = 5
.
Vá para o shell python e execute a operação passo a passo:
Integer
: Como o nome sugere, nada mais é do que um valor numérico que pode ser positivo, negativo ou zero sem um ponto decimal.
>>> num = 5
>>> print(num)
5
>>> type(num)
Como você pode ver aqui, declaramos um num
variável e atribuído 5 como um valor. O Python está embutido type
O método pode ser usado para verificar o tipo de variável. Quando verificamos o tipo de num, estamos vendo a saída
. Por enquanto, concentre-se apenas no int
nessa saída. Int representa um número inteiro.
Float
: É o mesmo que um número inteiro, mas com uma pequena diferença, um valor numérico com uma casa decimal.
>>> num = 5.0
>>> print(num)
5.0
>>> type(num)
Aqui atribuímos um número com um único decimal ao num
. Quando verificamos o tipo de num, podemos ver que é flutuante.
String
: Nada mais é do que uma formação de caracteres ou números inteiros. Eles podem ser representados usando aspas duplas ou simples.
>>> greet = "Hello user"
>>> print(greet)
Hello user
>>> type(greet)
Aqui atribuímos uma string para greet
. O tipo de saudação é uma string, como você pode ver na saída.
Boolean
: Eles são um operador binário com um valor Verdadeiro ou Falso.
>>> is_available = True
>>> print(is_available)
True
>>> type(is_available)
Aqui atribuímos um valor True para is_available
. O tipo dessa variável é booleano. Você só pode atribuir Verdade ou Falso. Lembrar T e F deve ser maiúsculo ou ocorrerá um erro da seguinte maneira:
>>> is_available = true
Traceback (most recent call last):
File "", line 1, in
NameError: name 'true' is not defined
NoneType
: É usado quando não temos o valor da variável.
>>> num = None
>>> print(num)
None
>>> type(num)
Operadores:
Consulte a imagem abaixo para entender todo o operador aritmético disponível em python com os seguintes exemplos:

Vamos entender os operadores um por um.
Operadores aritméticos: Sob esse operador, vem adição, subtração, exclusão, exponenciação, módulo e divisão de piso. Também a sintaxe abreviada.
Primeiro, declararemos duas variáveis a e b.
>>> a = 6 # Assignment
>>> b = 2
Vamos tentar nossas operações aritméticas básicas:
>>> a + b # Addition
8
>>> a - b # Subtraction
4
>>> a * b # Multiplication
12
>>> a / b # Division
3.0
>>> a ** b # Exponentiation
36
Para testar outras operações aritméticas, vamos alterar o valor de a
e b
.
>>> a = 7
>>> b = 3
>>> a % b # Modulus
1
>>> a // b # Floor division
2
Operações aritméticas abreviadas também estão disponíveis em python. Consulte a imagem e você pode testá-la da mesma maneira que acima. Para imprimir, a saída da operação abreviada usa a instrução print.
Operadores de comparação: Sob esse operador, vem igual, maior que, menor que.
>>> a = 5 # Assign
>>> b = 2 # Assign
>>> a > b # Greater than
True
>>> a < b # less then
False
>>> a == b # Equal to
False
>>> a >= 5 # Greater than or equal to
True
>>> b <= 1 # Less than or equal to
False
Operadores lógicos: Sob este operador não vem, e, ou.
>>> a = 10
>>> b = 2
>>> a == 2 and b == 10 # and
False
>>> a == 10 or b == 10 # or
True
>>> not(a == 10) # not
False
>>> not(a == 2)
True
Declarações condicionais:
Como o nome sugere, instruções condicionais são usadas para avaliar se uma condição é verdadeira ou falsa. Muitas vezes, ao desenvolver um aplicativo, é necessário verificar uma determinada condição e, dependendo da execução, é necessário executar ou você deve pular essa parte ou encerrar. Nesses cenários, declarações condicionais são úteis. If, elif e else são as instruções condicionais usadas em python.
Podemos comparar a variável, verificar se a variável tem algum valor ou se é um booleano e depois verificar se é verdadeira ou falsa. Vá para o shell python e execute a operação passo a passo:
Número da condição 1: Temos um número inteiro e três condições aqui. O primeiro é o if
doença. Está verificando se o número é igual a 10. O segundo é o elif
doença. Aqui estamos verificando se o número é menor que 10. A última condição é else
. Essa condição é executada quando nenhuma das condições acima corresponde.
>>> number = 5
>>> if number == 10:
... print("Number is 10")
... elif number < 10:
... print("Number is less than 10")
... else:
... print("Number is more than 10")
...
Resultado:
Number is less than 10
Nota: Não é obrigatório verificar se duas condições são iguais no if
doença. Você pode fazer isso no elif
Ademais.
Número da condição 2: Temos duas condições booleanas e duas aqui. Você notou como estamos verificando se a condição é verdadeira. E se is_available
depois imprima disponível ou imprima não disponível.
>>> is_available = True
>>> if is_available:
... print("Yes it is available")
... else:
... print("Not available")
...
Resultado:
Yes it is available
Número da condição 3: Aqui, revertemos o número da condição 2 com a ajuda de não operador.
>>> is_available = True
>>> if not is_available:
... print("Not available")
... else:
... print("Yes it is available")
...
Resultado:
Yes it is available
Número da condição 4: Aqui estamos declarando os dados como Nenhum e verificando se os dados estão disponíveis ou não.
>>> data = None
>>> if data:
... print("data is not none")
... else:
... print("data is none")
...
Resultado:
data is none
Número da condição 5: Você também pode usar inline se estiver em python. A sintaxe para conseguir isso é a seguinte:
>>> num_a = 10
>>> num_b = 5
>>> if num_a > num_b: print("num_a is greater than num_b")
...
Resultado:
num_a is greater than num_b
Número da condição 6: Você também pode usar o inline, caso contrário, em python. A sintaxe para conseguir isso é a seguinte:
expression_if_true if condition else expression_if_false
Exemplo:
>>> num = 5
>>> print("Number is five") if num == 5 else print("Number is not five")
Resultado:
Number is five
Número condicional 7: Você também pode usar if-else aninhado em python. A sintaxe para conseguir isso é a seguinte:
>>> num = 25
>>> if num > 10:
... print("Number is greater than 10")
... if num > 20:
... print("Number is greater than 20")
... if num > 30:
... print("Number is greater than 30")
... else:
... print("Number is smaller than 10")
...
Resultado:
Number is greater than 10
Number is greater than 20
Número da condição 8: Você também pode usar and
operador em uma declaração condicional. Ele declara se a condição1 e a condição2 são verdadeiras, então execute-a.
>>> num = 10
>>> if num > 5 and num < 15:
... print(num)
... else:
... print("Number may be small than 5 or larger than 15")
...
Resultado:
10
Como nosso número está entre 5 e 15, obtemos a saída 10.
Número da condição 9: Você também pode usar or
operador em uma declaração condicional. Ele afirma que, se a condição1 ou a condição2 for verdadeira, execute-a.
>>> num = 10
>>> if num > 5 or num < 7:
... print(num)
...
Resultado:
10
Você está confuso porque o valor de num
é 10 e nossa segunda condição afirma que num
é menor que 7? Então, por que obtemos a saída como 10? É por causa do or
doença. Quando uma das condições corresponder, ela será executada.
Para loops:
Outro método útil em qualquer linguagem de programação é um iterador. Considere que você precisa implementar algo várias vezes, o que você fará?
print("Hello")
print("Hello")
print("Hello")
Bem, essa é uma maneira de fazer isso. Mas imagine que você precise fazer isso cem ou mil vezes. Bem, são muitas as declarações impressas que temos que escrever. Espere, há uma solução disponível. É chamado de iteradores ou loops. Nós podemos usar um for
ou while
ciclo.
Aqui estamos usando o método range. Ele especifica o intervalo até o qual o loop deve ser repetido. Por padrão, o ponto inicial é 0.
>>> for i in range(3):
... print("Hello")
...
Resultado:
Hello
Hello
Hello
Você também pode especificar o intervalo dessa maneira range(1,3)
.
>>> for i in range(1,3):
... print("Hello")
...
Resultado:
Hello
Hello
Veja Olá é impresso apenas duas vezes, conforme especificamos o intervalo aqui. Considere que tem Number on right - Number on left
equação.
Bem, você também pode adicionar uma instrução else no loop for.
>>> for i in range(3):
... print("Hello")
... else:
... print("Finished")
Resultado:
Hello
Hello
Hello
Finished
Veja nosso loop iterado 3 vezes (3 - 0) e, uma vez feito isso, ele executou a instrução else.
Também podemos aninhar um loop for dentro de outro loop for.
>>> for i in range(3):
... for j in range(2):
... print("Inner loop")
... print("Outer loop")
...
Resultado:
Inner loop
Inner loop
Outer loop
Inner loop
Inner loop
Outer loop
Inner loop
Inner loop
Outer loop
Como você pode ver, a instrução de impressão do loop interno é executada duas vezes. Após essa instrução de impressão do loop externo ser executada. Novamente, o loop interno é executado duas vezes. Então o que está acontecendo aqui? Se você está confuso, considere isso para resolvê-lo:
- Nosso intérprete vem e vê ahh! existe um
for
ciclo. Desce novamente e verifica se há outrafor
ciclo. - Então agora ele irá executar o interior
for
loop duas vezes e saia. Uma vez feito isso, ele sabe que o loop for externo o instruiu a repetir mais duas vezes. - Começa novamente e vê o loop for interno e se repete.
Bem, você também pode optar por passar um certo for
condição de loop. O que significa pass aqui? Bem, sempre que esse loop for ocorrer e o intérprete vir o pass
declaração não o executará e passará para a próxima linha.
>>> for i in range(3):
... pass
...
Você não obterá nenhuma saída no shell.
Enquanto loops:
Outro loop ou iterador disponível em python é while
ciclo. Podemos obter alguns resultados com a ajuda de um while
loop como alcançamos com o for
ciclo.
>>> i = 0
>>> while i < 5:
... print("Number", i)
... i += 1
...
Resultado:
Number 0
Number 1
Number 2
Number 3
Number 4
Lembre-se sempre que você usa um loop while, é importante adicionar uma instrução de incremento ou uma instrução que levará ao fim do loop while em algum momento. Caso contrário, o loop while será executado para sempre.
Outra opção é adicionar um break
declaração em um while
ciclo. Isso vai quebrar o ciclo.
>>> i = 0
>>> while i < 5:
... if i == 4:
... break
... print("Number", i)
... i += 1
...
Resultado:
Number 0
Number 1
Number 2
Number 3
Aqui estamos quebrando o while
loop se encontrarmos o valor de i
ser 4.
Outra opção é adicionar um else
declaração em while
ciclo. A instrução será executada após o loop while ser concluído.
>>> i = 0
>>> while i < 5:
... print("Number", i)
... i += 1
... else:
... print("Number is greater than 4")
...
Resultado:
Number 0
Number 1
Number 2
Number 3
Number 4
Number is greater than 4
o continue
A instrução pode ser usada para pular a execução atual e prosseguir para a próxima.
>>> i = 0
>>> while i < 6:
... i += 1
... if i == 2:
... continue
... print("number", i)
...
Resultado:
number 1
number 3
number 4
number 5
number 6
Entrada do usuário:
Imagine que você está construindo um aplicativo de linha de comando. Agora você tem que pegar a entrada do usuário e agir de acordo. Aí vem o método embutido do python input
.
A sintaxe para conseguir isso é a seguinte:
variable = input(".....")
Exemplo:
>>> name = input("Enter your name: ")
Enter your name: Sharvin
Quando você usa o input
método e pressione enter. Você será solicitado com o texto digitado no input
método. Vamos verificar se nossa tarefa está funcionando ou não?
>>> print(name)
Sharvin
Aí está!! está funcionando perfeitamente. Aqui Sharvin
é do tipo string.
>>> type(name)
Vamos tentar mais um exemplo em que atribuiremos um número inteiro ao invés de uma string e verificaremos o tipo.
>>> date = input("Today's date: ")
Today's date: 12
>>> type(date)
Você está confuso?? Nós inserimos um número inteiro 12 e ele ainda está nos dando seu tipo como uma string. Não é um bug. É como a entrada se destina a funcionar. Para converter a string em número inteiro, usaremos typecast.
Typecasting:
Vimos que o input
O método retorna uma sequência para o número inteiro também. Agora, queremos comparar essa saída com outro número inteiro, então precisamos de uma maneira de convertê-la novamente em um número inteiro. Aí vem a tipografia em jogo.
>>> date_to_int = int(date)
>>> type(date_to_int)
Aqui pegamos a data que declaramos acima na seção de entrada do usuário e a convertemos em número inteiro usando o método int embutido do python. Isso é chamado de conversão de tipo.
Basicamente, você pode fazer a seguinte conversão com a ajuda da conversão de tipo:
- inteiro para string:
str()
- string para inteiro:
int()
- número inteiro para flutuar:
float()
Nota: A conversão de float para inteiro também é possível.
>>> type(date)
# Converting from string to float
>>> date_to_float = float(date)
>>> type(date_to_float)
# Converting from float to string
>>> date_to_string = str(date_to_float)
>>> type(date_to_string)
# Converting from float to integer
>>> date_to_int = int(date_to_float)
>>> type(date_to_int)
Dicionários:
Imagine que você deseja armazenar alguns detalhes do usuário. Então, como você pode armazenar esses detalhes? Sim, podemos usar a variável para armazená-los da seguinte maneira:
>>> fname = "Sharvin"
>>> lname = "Shah"
>>> profession = "Developer"
Para acessar esse valor, podemos acessá-los da seguinte maneira:
>>> print(fname)
Sharvin
Mas essa é uma maneira elegante e otimizada de acessá-lo? A resposta é não. Para torná-lo mais amigável e armazenar os dados em um dicionário de valores-chave, vem em nosso socorro.
O que é um dicionário? Um dicionário é uma coleção desordenada e mutável (ou seja, pode ser atualizada).
A seguir está o formato do dicionário:
data = {
"key" : "value"
}
Vamos entender o dicionário ainda mais com um exemplo:
>>> user_details = {
... "fname": "Sharvin",
... "lname": "Shah",
... "profession": "Developer"
... }
Valor de acesso no dict: Podemos acessar o valor dentro de um dicionário de duas maneiras. Primeiro entenderemos os dois caminhos e, em seguida, iremos depurar para descobrir qual caminho é melhor.
Caminho_No_1: Para acessar o valor de fname
chave de user_details
No dicionário, podemos usar a seguinte sintaxe:
>>> user_details["fname"]
'Sharvin'
Way_No_2: Também podemos acessar o valor de fname
chave de user_details
dicionário usando get
.
>>> user_details.get("fname")
'Sharvin'
Eu sei que Way_No_1 parece mais fácil de entender. O problema dessa maneira é quando tentamos acessar os dados que não estão disponíveis em nosso dicionário.
>>> user_details["age"]
Traceback (most recent call last):
File "", line 1, in
KeyError: 'age'
Temos um KeyError que indica que a chave não está disponível. Vamos tentar o mesmo cenário com o Way_No_2.
>>> user_details.get("age")
Não temos nada impresso em nosso console. Vamos depurar ainda mais para saber por que isso aconteceu? Atribua uma idade variável ao nosso get
operação e vamos imprimi-lo em nosso console.
>>> age = user_details.get("age")
>>> print(age)
None
Ahh !! Então quando get
não encontra a chave que define o valor como None e, por isso, não obtemos nenhum erro. Agora você pode estar se perguntando qual é o certo? Na maioria das vezes, o uso do Way_No_2 faz mais sentido, mas para algumas condições rigorosas de verificação, precisamos usar o Way_No_1.
Verifique se a chave existe: Você pode estar se perguntando como verificar se o dicionário é uma chave específica ou não em python. Python fornece um método embutido keys()
para resolver esse problema.
>>> if "age" in user_details.keys():
... print("Yes it is present")
... else:
... print("Not present")
...
Obteremos a seguinte saída:
Not present
E se quisermos verificar se o dicionário está vazio ou não? Para entender isso, vamos declarar um dicionário vazio da seguinte maneira:
>>> user_details = {}
Quando usamos o if-else diretamente em um dicionário, ele retorna true se os dados estiverem presentes ou false se estiver vazio.
>>> if user_details:
... print("Not empty")
... else:
... print("Empty")
...
Resultado:
Empty
Também podemos usar o método embutido do python bool
para verificar se o dicionário está vazio ou não. Lembre-se de que bool retorna False se o dicionário estiver vazio e True se estiver preenchido.
>>> bool(user_details)
False
>>> user_details = {
... "fname" : "Sharvin"
... }
>>> bool(user_details)
True
Atualize o valor da chave existente: Então agora sabemos como obter uma chave específica e descobrir se ela existe, mas como atualizá-la no dicionário?
Declare um dicionário da seguinte maneira:
>>> user_details = {
... "fname":"Sharvin",
... "lname": "Shah",
... "profession": "Developer"
... }
Para atualizar o valor, use a seguinte sintaxe:
>>> user_details["profession"] = "Software Developer"
>>> print(user_details)
{'fname': 'Sharvin', 'lname': 'Shah', 'profession': 'Software Developer'}
Atualizar um valor de chave no dicionário é o mesmo que atribuir um valor à variável.
Adicionando par de valores-chave: A próxima pergunta é como adicionar um novo valor ao dicionário? Vamos adicionar um age
chave com um valor de 100.
>>> user_details["age"] = "100"
>>> print(user_details)
{'fname': 'Sharvin', 'lname': 'Shah', 'profession': 'Software Developer', 'age': '100'}
Como você pode ver, um novo valor-chave é adicionado em nosso dicionário.
Removendo o par de valores-chave: Para remover um valor-chave do dicionário, o python fornece um método embutido chamado pop
.
>>> user_details.pop("age")
'100'
>>> print(user_details)
{'fname': 'Sharvin', 'lname': 'Shah', 'profession': 'Software Developer'}
Isso remove o par de valores-chave de idade do dicionário user_details. Também podemos usar um del
operador para excluir o valor.
>>> del user_details["age"]
>>> print(user_details)
{'fname': 'Sharvin', 'lname': 'Shah', 'profession': 'Software Developer'}
o del
O método também pode ser usado para excluir dicionário completo. Use a seguinte sintaxe para excluir o dicionário completo del user_details
.
Copie um dicionário: Um dicionário não pode ser copiado da maneira tradicional. Por exemplo, você não pode copiar o valor de dictA para dictB da seguinte maneira:
dictA = dictB
Para copiar os valores, você precisa usar o copy
método.
>>> dictB = user_details.copy()
>>> print(dictB)
{'fname': 'Sharvin', 'lname': 'Shah', 'profession': 'Software Developer'}
Listas:
Considere que você tem um monte de dados que não são rotulados (ou seja, ele não tem uma chave que os define). Então, como você os armazenará? E aqui vem Listas em nosso socorro. Eles estão definidos da seguinte forma:
data = [ 1, 5, "xyz", True ]
Uma lista é uma coleção de dados aleatórios, ordenados e mutáveis (ou seja, podem ser atualizados).
Elementos da lista de acesso: Vamos tentar acessar o primeiro elemento:
>>> data[1]
5
Espera o que aconteceu aqui? Estamos tentando acessar o primeiro elemento, mas estamos recebendo o segundo elemento. Por quê? A indexação da lista começa do zero. Então, o que quero dizer com isso? A indexação da posição dos elementos começa do zero. A sintaxe para acessar um elemento é a seguinte:
list[position_in_list]
Para acessar o primeiro elemento, precisamos acessá-lo da seguinte maneira:
>>> data[0]
1
Você também pode especificar um intervalo para acessar o elemento entre essas posições.
>>> data[2:4]
['xyz', True]
Aqui o primeiro valor representa o início, enquanto o último valor representa a posição até a qual queremos o valor.
Adicione um item à lista: Para adicionar um item na lista, precisamos usar o método append fornecido pelo python.
>>> data.append("Hello")
>>> data
[1, 5, 'abc', True, 'Hello']
Alterar valor do item: Para alterar o valor de um item, use a seguinte sintaxe:
>>> data[2] = "abc"
>>> data
[1, 5, 'abc', True]
Remova o item da lista: Para remover um item de uma lista, podemos usar os recursos embutidos do python remove
método.
>>> data.remove("Hello")
>>> data
[1, 5, 'abc', True]
Percorra uma lista: Também podemos percorrer a lista para encontrar um determinado elemento e operá-lo.
>>> for i in data:
... print(i)
...
Resultado:
1
5
abc
True
Verifique se o item existe ou não: Para verificar se um item específico existe ou não está na lista, podemos usar o loop if da seguinte maneira:
>>> if 'abc' in data:
... print("yess..")
...
yess..
Cópia de: Para copiar os dados de uma lista de uma lista para outra, precisamos usar copy
método.
>>> List2 = data.copy()
>>> List2
[1, 5, 'abc', True]
Comprimento: Também podemos verificar o tamanho da lista usando o recurso embutido do Python len
método.
>>> len(data)
4
Junte-se a duas listas: Para juntar duas listas, podemos usar +
operador.
>>> list1 = [1, 4, 6, "hello"]
>>> list2 = [2, 8, "bye"]
>>> list1 + list2
[1, 4, 6, 'hello', 2, 8, 'bye']
O que acontece se tentarmos acessar uma posição do elemento que não está disponível na lista? Temos um list index out of range error
em tal condição.
>>> list1[6]
Traceback (most recent call last):
File "", line 1, in
IndexError: list index out of range
Tuplas:
A tupla é de um tipo de dados que é ordenado e imutável (ou seja, os dados não podem ser alterados)
Vamos criar uma tupla:
>>> data = ( 1, 3 , 5, "bye")
>>> data
(1, 3, 5, 'bye')
Acesse o elemento da tupla: Podemos acessar elementos na tupla da mesma maneira que acessamos na lista:
>>> data[3]
'bye'
Podemos acessar o intervalo de índice da seguinte maneira:
>>> data[2:4]
(5, 'bye')
Alterar o valor da tupla: Se você está pensando em como podemos alterar o valor da tupla, você está certo, meu amigo. Não podemos alterar o valor da tupla, pois é imutável. Obtemos o seguinte erro se tentarmos alterar o valor da tupla:
>>> data[1] = 8
Traceback (most recent call last):
File "", line 1, in
TypeError: 'tuple' object does not support item assignment
Existe uma solução alternativa disponível para alterar o valor da tupla:
>>> data = ( 1, 3 , 5, "bye")
>>> data_two = list(data) # Convert data to list
>>> data_two[1] = 8 # Update value as list is mutable
>>> data = tuple(data_two) # Convert again to tuple
>>> data
(1, 8, 5, 'bye')
Todos os outros métodos que vimos na lista também são aplicáveis à tupla.
[ Note: Once a tuple is created a new value cannot be added in it. ].
Conjuntos:
Sets é outro tipo de dados em python que não é ordenado e não indexado. Os conjuntos são declarados da seguinte maneira:
>>> data = { "hello", "bye", 10, 15 }
>>> data
{10, 15, 'hello', 'bye'}
Valor de acesso: Como os conjuntos não são indexados, não podemos acessar diretamente o valor em um conjunto. Portanto, para acessar o valor no conjunto, você precisa usar um loop for.
>>> for i in data:
... print(i)
...
10
15
hello
bye
Alterar valor: Depois que o conjunto é criado, os valores não podem ser alterados.
Adicionar Item: Para adicionar um item ao conjunto, o python fornece um método embutido chamado add
.
>>> data.add("test")
>>> data
{10, 'bye', 'hello', 15, 'test'}
Verifique o comprimento: Para verificar a duração do conjunto, usamos o len
método.
>>> len(data)
5
Remover item: Para remover um item, use o remove
método:
>>> data.remove("test")
>>> data
{10, 'bye', 'hello', 15}
Funções e argumentos:
As funções são uma maneira útil de declarar uma operação que queremos executar. Com a ajuda da função, você pode separar a lógica de acordo com a operação.
Eles são um bloco de código que nos ajuda na reutilização da lógica repetitiva. As funções podem ser incorporadas e definidas pelo usuário.
Para declarar uma função, usamos o def
palavra-chave A seguir, é apresentada a sintaxe das funções:
>>> def hello_world():
... print("Hello world")
...
Aqui estamos declarando uma função que, quando chamada, imprime uma declaração Hello world. Para chamar uma função, usamos a seguinte sintaxe.
>>> hello_world()
Obteremos a seguinte saída:
Hello world
Lembrar ()
suporte em uma chamada de função significa executá-lo. Remova os colchetes e tente a chamada novamente.
>>> hello_world
Você obterá a seguinte saída:
Quando removemos o colchete da chamada de função, ele nos fornece uma referência de função. Aqui acima, como você pode ver a referência de function hello_world
aponta para este endereço de memória 0x1083eb510
.
Considere que você deve executar uma operação de adição. Você pode fazer isso declarando aeb executando a adição.
>>> a = 5
>>> b = 10
>>> a + b
15
Este é um caminho a percorrer, mas agora considere o valor de a
e b
mudaram e você precisa fazê-lo novamente.
>>> a = 5
>>> b = 10
>>> a + b
15
>>> a = 2
>>> b = 11
>>> a + b
13
Isso ainda parece factível. Agora imagine que precisamos adicionar um conjunto de dois números cem vezes. Os números dentro do conjunto são diferentes para cada cálculo. Isso é muito o que fazer. Não se preocupe, temos uma função à nossa disposição para resolver esse problema.
>>> def add(a,b):
... print(a+b)
...
Aqui estamos adicionando a
e b
como argumento obrigatório ao add
função. Para chamar essa função, usaremos a seguinte sintaxe:
>>> add(10,5)
Resultado:
15
Veja como é fácil definir uma função e usá-la. Então, o que acontece se não aprovarmos uma discussão?
>>> add()
Traceback (most recent call last):
File "", line 1, in
TypeError: add() missing 2 required positional arguments: 'a' and 'b'
Python lança um TypeError e nos informa que a função requer dois argumentos.
Você consegue adivinhar o que acontecerá se aprovarmos um terceiro argumento?
>>> add(10,5,1)
Traceback (most recent call last):
File "", line 1, in
TypeError: add() takes 2 positional arguments but 3 were given
Bem, o python nos informará que passamos 3 argumentos, mas existem apenas 2 argumentos posicionais.
Então, o que podemos fazer quando não sabemos quantos argumentos uma função pode levar? Para resolver esse problema, usamos args e kwargs.
Args:
Quando você não sabe quantos argumentos serão passados para a função, args e kwargs são usados nesse cenário.
Para passar n número de argumentos para uma função, usamos args. Nós adicionamos um *
por trás da discussão.
Lembre-se de quando você anexa um
*
na frente, você receberá uma tupla de argumentos.
>>> def add(*num):
... print(num)
...
Aqui *num
é um argumento. Agora, quando chamamos a função add
podemos passar n número de argumentos e não lançará um TypeError
.
>>> add(1,2,3)
(1, 2, 3)
>>> add(1,2,3,4)
(1, 2, 3, 4)
Agora, para executar a operação de adição, usaremos a função interna do Python sum
>>> def add(*num):
... print(sum(num))
...
Agora, quando chamamos a função add, obteremos a seguinte saída:
>>> add(1,2,3) # Function call
6
>>> add(1,2,3,4) # Function call
10
Argumentos de palavras-chave:
Há alguma condição em que não sabemos a ordem de como os argumentos serão transmitidos para a função quando forem chamados. Nesse cenário, usamos argumentos de palavras-chave porque você pode transmiti-los em qualquer ordem em sua chamada e nossa função saberá o valor. Vamos entender esse conceito por exemplo.
>>> def user_details(username, age):
... print("Username is", username)
... print("Age is", age)
...
Vamos chamar essa função da seguinte maneira:
>>> user_details("Sharvin", 100)
Obteremos a seguinte saída:
Username is Sharvin
Age is 100
Bem, isso parece correto, mas imagine se chamamos nossa função dessa maneira:
>>> user_details(100, "Sharvin")
Obteremos a seguinte saída:
Username is 100
Age is Sharvin
Isso não parece certo. O que aconteceu é username
assumiu o valor de 100 enquanto age
tomou o valor de Sharvin. Em cenários como este, onde não sabemos a ordem dos argumentos, podemos usar argumentos de palavras-chave ao chamar a função da seguinte maneira:
>>> user_details(age=100, username="Sharvin")
Resultado:
Username is Sharvin
Age is 100
Veja que isso é mágico, temos nossa saída correta.
Argumento padrão:
Suponha que exista uma condição em que não tenhamos certeza se um argumento específico obterá um valor ou não quando a função for chamada. Nesse cenário, podemos usar argumentos padrão da seguinte maneira:
>>> def user_details(username, age = None):
... print("Username is", username)
... print("Age is", age)
...
Aqui estamos atribuindo um None
ao nosso argumento da idade. Se não passarmos o segundo argumento enquanto chamamos a função, será usado None como valor padrão.
Vamos chamar a função:
>>> user_details("Sharvin")
Resultado:
Username is Sharvin
Age is None
Lembre-se de que quando passamos o segundo argumento, nesse cenário, ele substituirá o Nenhum e o utilizará como valor.
>>> user_details("Sharvin", 200)
Username is Sharvin
Age is 200
O que acontecerá se for atribuído o primeiro argumento em nossa função como padrão e o segundo como argumento obrigatório? Vá para o shell python e tente isso.
>>> def user_details(username=None, age):
... print("Username is", username)
... print("Age is", age)
...
Você receberá o seguinte erro:
File "", line 1
SyntaxError: non-default argument follows default argument
Lembrar: Todos os argumentos obrigatórios devem ser declarados primeiro e, em seguida, o argumento padrão deve ser declarado.
kwargs:
Pode haver uma situação em que você não sabe quantos argumentos de palavras-chave serão passados para a função. Nesse cenário, podemos usar o Kwargs.
Para usar kwargs, colocamos **
na frente do argumento.
Lembrar: Quando você anexa um
**
na frente, você receberá um dicionário de argumentos.
Vamos entender isso por exemplo. Declararemos uma função que aceita nome de usuário como argumento com **
na frente dele.
>>> def user(**username):
... print(username)
...
Quando chamamos o user
funcionar da seguinte maneira, receberemos um dicionário.
>>> user(username1="xyz",username2="abc")
Resultado:
{'username1': 'xyz', 'username2': 'abc'}
Então, o que está acontecendo aqui? Parece o mesmo que Args, certo? Não, não é. Nos argumentos, você não pode acessar um valor específico por seu nome, pois ele está na forma de uma tupla. Aqui obtemos os dados na forma de um dicionário. Para que possamos acessar facilmente o valor. Considere este exemplo:
>>> def user(**user_details):
... print(user_details['username'])
...
Vamos chamar nossa função:
>>> user(username="Sharvin",age="1000")
E você obterá a seguinte saída:
Sharvin
Escopo:
Um escopo define onde uma variável ou função está disponível. Existem dois tipos de escopo em python, ou seja, Global e Local.
Âmbito global: Uma variável ou função criada no corpo principal do código python é chamada de variável ou função global e faz parte do escopo global. Vamos entender esse conceito por exemplo:
>>> greet = "Hello world"
>>> def testing():
... print(greet)
...
>>> testing()
Hello world
Aqui, a variável greet está disponível globalmente porque é declarada no corpo do python.
Escopo local: Uma variável ou função criada dentro de uma função é chamada de variável ou função local e faz parte do escopo local. Vamos entender esse conceito por exemplo:
>>> def testing():
... greet = "Hello world"
... print(greet)
...
>>> testing()
Hello world
Aqui o greet é criado dentro da função de teste e está disponível apenas lá. Vamos tentar acessá-lo em nosso corpo principal e ver o que acontece.
>>> print(greet)
Traceback (most recent call last):
File "", line 1, in
NameError: name 'greet' is not defined
Lembrar: Para testar a condição acima, lembre-se de reiniciar o console python clicando em ctrl + d e iniciando novamente o shell python usando python3
comando. A razão por trás disso é que já declaramos greet
variáveis em nosso escopo global e está disponível em nossa memória.
Como o greet não está disponível globalmente, obtemos o erro de que ele não está definido.
Declaração de retorno:
Até agora, nossas funções são praticamente estúpidas. Eles estão recebendo os dados, processando-os e imprimindo-os. Mas no mundo real, você precisa de uma função para fornecer saída. Para que essa saída possa ser usada em diferentes operações.
Para isso, são utilizadas instruções de retorno. Lembre-se de que as instruções de retorno são apenas parte de funções e métodos. A sintaxe para a declaração de retorno é bastante fácil.
>>> def add(a, b):
... return a + b
...
>>> add(1,3)
4
Em vez de imprimir nossa adição, estamos retornando a saída. O valor da saída retornada também pode ser armazenado em uma variável.
>>> sum = add(5,10)
>>> print(sum)
15
Expressão Lambda:
Considere uma situação em que você não deseja executar muita computação em uma função. Em tal situação, escrever uma função completa não faz sentido. Para resolver isso, usamos uma expressão lambda.
Então, o que é uma função lambda? É uma função anônima e eles estão restritos a uma única expressão. A função lambda pode receber n número de argumentos.
A sintaxe da função lambda é:
variable = lambda arguments: operation
Vamos entender mais por exemplo:
>>> sum = lambda a: a + 10
Aqui declaramos uma variável sum
que estamos usando para chamar a função lambda. a
representa o argumento que é passado para essa função.
Vamos chamar nossa função:
>>> x(5)
15
Compreensão da lista:
Considere uma situação em que você deseja uma lista de quadrados. Normalmente você declarará um squares
lista e, em um loop for, você quadrará os números.
>>> squares = []
>>> for x in range(10):
... squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Bem, isso é possível, mas podemos conseguir isso em uma única linha com a ajuda da compreensão da lista.
Existem duas maneiras de conseguir isso. Vamos entender os dois.
>>> squares = list(map(lambda x: x**2, range(10)))
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Aqui estamos usando list
construtor para criar uma lista e dentro dessa função lambda que esquadrinha o número. Outra maneira de obter o mesmo resultado é a seguinte:
>>> squares = list(x**2 for x in range(10))
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Eu prefiro assim porque é mais fácil de entender devido à sua legibilidade e concisão.
E quando temos uma condição em que queremos um conjunto de dois números iguais. Bem, precisamos escrever dois para loops e um se.
Vamos ver como isso será:
>>> num_list = []
>>> for i in range(10):
... for j in range(10):
... if i == j:
... num_list.append((i,j))
...
>>> num_list
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9)]
Isso dá muito trabalho e, em termos de legibilidade, é difícil de entender.
Vamos usar a compreensão da lista para obter o mesmo resultado.
>>> num_list = list((i,j) for i in range(10) for j in range(10) if i == j)
>>> num_list
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9)]
Consulte Como é fácil obter a mesma saída em uma única expressão. Bem, esse é o poder da compreensão da lista. Ao iniciar o desenvolvimento de um aplicativo, você descobrirá que a compreensão da lista é poderosa.
Conceitos OOPS:
Python é uma linguagem de programação com vários paradigmas. Isso significa que o python pode usar abordagens diferentes para resolver o problema. Um dos paradigmas é a programação processual ou funcional. Ele estrutura o código como uma receita; conjunto de etapas na forma de função e bloco de código.
Outra abordagem para resolver o problema é criar classes e objetos. Isso é conhecido como programação orientada a objetos. Um objeto é uma coleção de dados (variáveis) e métodos que atuam sobre esses dados. E, a classe é um modelo para o objeto.
The important part to understand in object-oriented programming is that objects are at the center of the paradigm, not only representing the data but it also represents the structure of the program.
You can choose the paradigm that best suits the problem at hand, mix different paradigms in one program, and/or switch from one paradigm to another as your program evolves.
Advantages of object oriented programming:
- Inheritance: This is one of the most useful concepts in oops. It specifies that the child object will have all the properties and behavior of the parent object. Thus Inheritance allows us to define a class that inherits all the methods and properties from another class.
- Polymorphism: To understand polymorphism let’s divide the word into two parts. The first part poly means many and morph means to form or shape. Thus in simple one-word polymorphism means one task can be performed in many different ways. For example, you have a class animal, and all animals speak. But they speak differently. Here, the “speak” behavior is polymorphic and depends on the animal. So, the abstract “animal” concept does not actually “speak”, but specific animals (like dogs and cats) have a concrete implementation of the action “speak”. Polymorphism means the same function name or method name being used for different types.
- Encapsulation: In object-oriented programming you can restrict access to methods and variables; we can make the methods and variables private. This can prevent the data from being modified by accident and is known as encapsulation.
First, we will understand classes, objects, constructor and after that, we will look into the above properties again. If you know about the classes, object, and constructor you can skip to the section that you want to read.
Classes:
There are primitive data structures available in python for example numbers, strings, and lists that can be used for simple representation like name, place or cost, etc.
But what if we have a condition where we have complex data. There is a pattern in the repetition of the properties of that data in that scenario what can we do?
Suppose we have a data of 100 different animals. Every animal has a name, age, legs, etc. What if we want to add other properties to animal or one more animal gets added to that list. To manage all such complex scenario’s we need classes.
According to official python documentation, Classes provide a means of bundling data and functionality together. Creating a new class creates a new type of object, allowing new instances of that type to be made.
Each class instance can have attributes attached to it for maintaining its state. Class instances can also have methods (defined by its class) for modifying its state.
Syntax of class:
class ClassName:
.
.
.
Nós usamos class
keyword to define a class. We will define a class Car
.
class Car:
pass
Methods:
Methods look the same like function only difference is that methods are dependent on the object. A function can be invoked by name while methods need to be invoked by using their class reference. They are defined inside the class.
In our example, let's create 2 methods. One is an engine and another is a wheel. These 2 methods define the parts available in our car.
The below program will give us a better idea of classes:
>>> class Car:
... def engine(self):
... print("Engine")
...
>>> Car().engine()
Engine
Here we are calling the engine
method by using the Car()
reference.
To summarise, the class provides a blueprint of what should be defined but it does not provide any real content. o Car
class above defines the engine but it will not state what a specific car’s engine is. It is specified by the object.
Objects:
If you are fully clear with classes and method we will move to objects. If you still have any doubt reread both the sections again.
The object is an instance of the class. Let’s consider the above example of a car. Here Car is our class
and toyota is the object
of the car. We can create multiple copies of the object. Every object must be defined using the class.
The syntax for creating an object is:
toyota = Car()
Let’s consider our Car example for understanding the objects more better.
class Car:
def engine(self):
print("Engine")
def wheel(self):
print("Wheel")
toyota = Car()
The above toyota = Car()
é um class object. Class objects support two kinds of operations: attribute references and instantiation.
Class instantiation uses function notation. The instantiation operation (“calling” a class object) creates an empty object.
Now we can call different methods from our class Car
using the object toyota
that we have created. let’s call the method engine
e wheel
.
Open your editor and create a file named mycar.py
. In that file copy the code below:
class Car:
def engine(self):
print("Engine")
def wheel(self):
print("Wheel")
if __name__ == "__main__":
toyota = Car()
toyota.engine()
toyota.wheel()
Save the above code. Let's under our program.
Here we are creating a toyota
object with the help of Car
classe. o toyota.engine()
is a method object. What exactly happens when a method object is called? In the call toyota.engine()
doesn't take any argument but if you see the method declaration we can see that it takes a self
argumento. You may be confused about why it is not throwing an error. Well whenever we use a method object, the call toyota.engine()
is converted to Car.engine(toyota)
. We will understand more about the self in the upcoming section.
Run the program using the following command.
python mycar.py
You'll get the following output:
Engine
Wheel
Constructor:
o __init__
method is the constructor method in python. The constructor method is used to initialize the data.
Go to the python shell and test the below example:
>>> class Car():
... def __init__(self):
... print("Hello I am the constructor method.")
...
When we will call our class we will get the following output:
>>> toyota = Car()
Hello I am the constructor method.
Nota: You will never have to call the init() method; it gets called automatically when you create a class instance.
Instance attributes:
All the classes have objects and all the objects have attributes. Attributes are the properties. Nós usamos __init__()
method to specify an object’s initial attribute.
Let’s consider our car example:
class Car():
def __init__(self, model):
self.model = model #instance attribute
In our example, each Car()
has a specific model. Thus instance attributes are unique data to each instance.
Class attributes:
We saw that instance attributes are specific to each object but class attributes are the same for all the instances. Let us look at the example of the car with the help of class attributes.
class Car():
no_of_wheels = 4 #class attribute
So each car can have different models but all the cars will have 4 wheels only.
Self:
Now let’s understand what does self
means and how we use it in object-oriented programming. o self
represents the instance of a class. Using the self
keyword we can access the data initialize in the constructor and methods of a class.
Let us look at an example of how the self
can be used. Let’s create a method named brand
under our class Car
.
Inside that __init__
method, we will pass a model by passing our car’s model name when we are instantiating our object. This name can be accessed anywhere in the class for example self.model
in our case.
Go to the file named mycar.py
and replace old code with this code:
class Car():
def __init__(self, model):
self.model = model
def brand(self):
print("The brand is", self.model)
if __name__ == "__main__":
car = Car("Bmw")
car.brand()
Now when we run our above program using the following command:
python mycar.py
We will get the following output:
The brand is Bmw
Nota:self
is a convention and not a real python keyword. UMA self
is a argument in method and we can use another name in place of it. But it is recommended to use self
because it increases the readability of code.
Inheritance:
When a class inherits the property of another class then this scenario is called inheritance.
The class from which properties are inherited is called the base class. The class which inherits the property of another class is called the derived class.
Inheritance can be defined as a parent and child relationship. The child inherits the properties of the parent. Thus making the child a derived class while parent as a base class. Here term property refers to attributes and methods.
The syntax for a derived class definition looks like this:
class DerivedClassName(BaseClassName):
.
.
.
It’s important to note that child classes override or extend the attributes and behaviors of parent class methods. In other words, child classes inherit all of the parent’s attributes and behaviors but can also specify different behavior to follow.
The most basic type of class is an object, which generally all other classes inherit as their parent. Let’s modify our previous example to understand how inheritance works.
We will create a base class named vehicle
:
class Vehicle:
def __init__(self, name):
self.name = name
def getName(self):
return self.name
We have created a class Vehicle
and instantiated a constructor with self.name
which we are using in getName
método. Whenever this method will be called, it will return the name
that has been passed when an object is instantiated for that class.
Now let’s create a child class Car
:
class Vehicle:
def __init__(self, name):
self.name = name
def getName(self):
return self.name
class Car(Vehicle):
pass
Car
is a child class of Vehicle
. It inherits all the method and attributes of parent class.
Now let’s use methods and attribute from the Vehicle
class in our child class Car
.
class Vehicle:
def __init__(self, name, color='silver'):
self.name = name
self.color = color
def get_name(self):
return self.name
def get_color(self):
return self.color
class Car(Vehicle):
pass
audi = Car("Audi r8")
print("The name of our car is", audi.get_name(), "and color is", audi.get_color())
Let's understand what we have done here. We have declared a class named Vehicle
with a constructor that takes name as an argument while color has default argument. We have two methods inside it. o get_name
returns name while the get_color
returns the color. We have instantiated a object and passed the car name.
One thing you'll notice here that we are using base class methods in our child class declaration.
Run the above program using the following command:
python mycar.py
Resultado:
The name of our car is Audi r8 and color is silver
We can also override a parent method or attribute. In the above example, we have defined our vehicle color has silver. But what if the color of our car is black?
Now for every child class, we can’t make changes in the parent class. There comes the overriding functionality.
class Vehicle:
def __init__(self, name, color='silver'):
self.name = name
self.color = color
def get_name(self):
return self.name
def get_color(self):
return self.color
class Car(Vehicle):
def get_color(self):
self.color = 'black'
return self.color
audi = Car("Audi r8")
print("The name of our car is", audi.get_name(), "and color is", audi.get_color()
As you can see in the above program, I have not instantiated a constructor. The reason behind this is that our child class Car
is only using attributes from the Vehicle
class and it is already inheriting them. So in such a scenario, there is no need to re-instantiate these attributes.
Now When we run the above program we will get the following output:
The name of our car is Audi r8 and color is black
Super:
o super()
returns a temporary object of the superclass that then allows us to call that superclass’s methods. Calling the previously built methods with super()
saves us from needing to rewrite those methods in our subclass, and allows us to swap out superclasses with minimal code changes. Thus super
extends the functionality of the inherited method.
Let’s extend our car example using super()
. We will instantiate a constructor with brand_name
e color
in the parent class; Vehicle
. Now we will call this constructor from our child class (Car
) using super
. We will create a get_description
method which is returning self.model
de Car
class and self.brand_name
, self.color
de Vehicle
classe.
class Vehicle:
def __init__(self, brand_name, color):
self.brand_name = brand_name
self.color = color
def get_brand_name(self):
return self.brand_name
class Car(Vehicle):
def __init__(self, brand_name, model, color):
super().__init__(brand_name, color)
self.model = model
def get_description(self):
return "Car Name: " + self.get_brand_name() + self.model + " Color:" + self.color
c = Car("Audi ", "r8", " Red")
print("Car description:", c.get_description())
print("Brand name:", c.get_brand_name())
When we run the above program we get following output:
Car description: Car Name: Audi r8 Color: Red
Brand name: Audi
Multiple Inheritance:
When a class inherits the method and attributes from multiple parent class then it is called multiple inheritance. This allows us to use the property from multiple base classes or parent classes in a derived or child class.
The general syntax of Multiple Inheritance is as follows:
class DerivedClassName(Base1, Base2, Base3):
.
.
.
Let’s extend our vehicle example using multiple inheritance property. Here in this example, we will create 3 classes i.e. Vehicle
, Cost
e Car
Classe Vehicle
e Cost
will be the Parent class. UMA Vehicle
class represents the general property while the Cost
class represents its pricing.
Enquanto o Car
has a general property and costing both it will have 2 parent classes. Thus we will inherit multiple parent classes.
class Vehicle:
def __init__(self, brand_name):
self.brand_name = brand_name
def get_brand_name(self):
return self.brand_name
class Cost:
def __init__(self, cost):
self.cost = cost
def get_cost(self):
return self.cost
class Car(Vehicle, Cost):
def __init__(self, brand_name, model, cost):
self.model = model
Vehicle.__init__(self, brand_name)
Cost.__init__(self, cost)
def get_description(self):
return self.get_brand_name() + self.model + " is the car " + "and it's cost is " + self.get_cost()
c = Car("Audi ", "r8", "2 cr")
print("Car description:", c.get_description())
Here you will find one difference in the above program than other programs from above. I have used Vehicle.__init__(self, brand_name)
in the constructor of Car
classe. This is one way of calling attributes from the parent class. Another being super
which I have explained above. When we run the above program we will get the following output:
Car description: Audi r8 is the car and it's cost is 2 cr
Though it can be used effectively, multiple inheritance should be done with care so that our programs do not become ambiguous and difficult for other programmers to understand.
Polymorphism:
The word polymorphism means having many forms. In programming, polymorphism means same function name (but different signatures) being uses for different types.
Let’s extend our car program using polymorphism. We will create 2 classes Car
e Bike
. Both the classes have common method or function but they are printing different data. The program is pretty much self-explanatory.
class Car:
def company(self):
print("Car belongs to Audi company.")
def model(self):
print("The Model is R8.")
def color(self):
print("The color is silver.")
class Bike:
def company(self):
print("Bike belongs to pulsar company.")
def model(self):
print("The Model is dominar.")
def color(self):
print("The color is black.")
def func(obj):
obj.company()
obj.model()
obj.color()
car = Car()
bike = Bike()
func(car)
func(bike)
When we run the above code we will get the following output:
Car belongs to Audi company.
The Model is R8.
The color is silver.
Bike belongs to pulsar company.
The Model is dominar.
The color is black.
Encapsulation:
In most of the object-oriented programming, we can restrict access to methods and variables. This can prevent the data from being modified by accident and is known as encapsulation. This is also available in python.
Let’s integrate encapsulation into our car example. Now consider we have a super-secret engine. In the first example, we will hide our engine using a private variable. In the second example, we will hide our engine using a private method.
Example 1:
class Car:
def __init__(self):
self.brand_name = 'Audi '
self.model = 'r8'
self.__engine = '5.2 L V10'
def get_description(self):
return self.brand_name + self.model + " is the car"
c = Car()
print(c.get_description)
print(c.__engine)
In this example self.__engine
is a private attribute. When we run this program we will get the following output.
Audi r8 is the car
AttributeError: 'Car' object has no attribute '__engine'
We get an error that Car
object doesn't have _engine because it is a private object.
Example 2:
We can also define a private method by adding __
in front of the method name. Following is the example of how we can define a private method.
class Car:
def __init__(self):
self.brand_name = 'Audi '
self.model = 'r8'
def __engine(self):
return '5.2 L V10'
def get_description(self):
return self.brand_name + self.model + " is the car"
c = Car()
print(c.get_description())
print(c.__engine())
In this example def __engine(self)
is a private method. When we run this program we will get the following output.
Audi r8 is the car
AttributeError: 'Car' object has no attribute '__engine'
Now suppose we want to access the private attribute or method we can do it in the following way:
class Car:
def __init__(self):
self.brand_name = 'Audi '
self.model = 'r8'
self.__engine_name = '5.2 L V10'
def __engine(self):
return '5.2 L V10'
def get_description(self):
return self.brand_name + self.model + " is the car"
c = Car()
print(c.get_description())
print("Accessing Private Method: ", c._Car__engine())
print("Accessing Private variable: ", c._Car__engine_name)
The output of following program is:
Audi r8 is the car
Accessing Private Method: 5.2 L V10
Accessing Private variable: 5.2 L V10
Encapsulation gives you more control over the degree of coupling in your code, it allows a class to change its implementation without affecting other parts of the code.
Decorator:
Imagine you have to extend the functionality of multiple functions. How will you do that? Well, one way is you can make functional calls and in that function, you can handle it. Making changes in 30 to 40 function calls and remembering where to place the call is a messy task. But there is a more elegant way provided by python and that is Decorator.
What is a decorator? A decorator is a function that takes a function and extends its functionality without modifying explicitly. Well, I understand if you are still confused about what decorators are. Don't worry we have a tool named example to explain it.
Let's try an example to understand the decorator. There are 2 ways to write a decorator.
Way 1: We declare a decorator function and in the arguments of the function we expect the function to be passed as an argument. Inside that, we write a wrapper function where operations are carried out and it is returned.
>>> def my_decorator(func):
... def wrapper():
... print("Line Number 1")
... func()
... print("Line Number 3")
... return wrapper
...
>>> def say_hello():
... print("Hello I am line Number 2")
...
To call the function we assign the decorator with say_hello
as an argument.
>>> say_hello = my_decorator(say_hello)
We can also check the reference using say_hello
. We will get the output that informs us it has been wrapped by the my_decorator
function.
.wrapper at 0x10dc84598>
Let's call our say_hello
function:
>>> say_hello()
Line Number 1
Hello I am line Number 2
Line Number 3
See the magic the line "Hello I am line Number 2" gets printed in between Line Number 1 and 3 because the function call get's executed there.
The way no 1 is clunky and because of that many people prefer way no 2. Let's understand it.
Way No 2: Here our decorator declaration remains same but we change how the call is assign to that decorator. Whichever function require that decorator wraps it self with @decorator_name
.
>>> def my_decorator(func):
... def wrapper():
... print("Line Number 1")
... func()
... print("Line Number 3")
... return wrapper
...
>>> @my_decorator
... def say_hello():
... print("Hello I am line Number 2")
...
>>> say_hello()
Output is the same:
Line Number 1
Hello I am line Number 2
Line Number 3
A decorator is a powerful tool and it is used in the following development scenario of an application:
- Setup logger
- Setup configuration
- Setup Error catching
- Extending common functionality for all function and classes
Exceptions:
When we were learning various syntax we came around various errors. Those were the error because of the syntax. But in a real-world application, errors or commonly known as a bug not only occur due to the syntax issue but also because of network error or some other cause.
To handle these issues we use Try - Except. No try
block, we write the expression that we want to be executed while in except
block we catch the error. Try-Except block looks as follows:
try:
expression
except:
catch error
Let's understand this by an example:
>>> try:
... print(value)
... except:
... print("Something went wrong")
...
Here we are trying to print value variable but it is not defined. So we get the following output:
Something went wrong
You may be wondering the line "something went wrong" is not that helpful. So how can I know what went wrong here?
We can the exception and use it to find out what went wrong. Let's test this in our example:
>>> try:
... print(value)
... except Exception as e:
... print(e)
...
And the result is:
name 'value' is not defined
Wooh!! that's magic. It is notifying me that 'value' is not defined.
Python also provides a tool named raise
. Suppose you don't want certain condition to occur and if it occurs you want to raise it. In such condition you can use it. Consider the example above:
>>> i = 5
>>> if i < 6:
... raise Exception("Number below 6 are not allowed")
...
The output we get is as follows:
Traceback (most recent call last):
File "", line 2, in
Exception: Number below 6 are not allowed
There are many sub type of Exception and I would recommend you to go through Python Documentation to understand them.
Package Import:
You have learned python and now you are all ready to build awesome applications. But before that wait for my friend. We are still missing some important topics.
Without package import, you will be forced to write everything in one single file. Imagine what a mess it will be.
Create two files named main.py
e hello.py
. Remember both file needs to be in same directory.
Under hello.py
copy paste the following code:
def say_hello():
print("Hello world")
Under main.py
copy paste the following code:
import hello
if __name__ == "__main__":
hello.say_hello()
No hello.py
we have declared a say_hello()
function which prints "Hello world". No main.py
you'll see a import statement. We are importing the hello module and calling say_hello() function from that module.
Run our program using the following command:
➜ python main.py
Resultado:
Hello world
Now let's understand how to import a module which is in another directory.
Let's create a directory named data and move our hello.py
inside that directory.
Vou ao main.py
and change the previous import statement.
from data import hello
if __name__ == "__main__":
hello.say_hello()
There are two ways to import from a directory.
- Way1: from data import hello
- Way2: import data.hello
I prefer way1 because of its readability. You can choose any way which you like.
Let's run our application using the following command:
➜ python main.py
And error occurs. Wait why did this happened? We did everything right. Let's see go through the error:
Traceback (most recent call last):
File "main.py", line 1, in
from data import hello
ImportError: No module named data
Well python is telling us that it doesn't know a module named data. To solve this issue create a __init__.py
inside data directory. Leave the file blank and run the program again and you'll get the following output:
Hello world
Well python by default does not treat a directory as module. To inform python to treat a directory as module, __init__.py
is required.
JSON Handling:
If you worked previously with web development or app development you may be aware that all the API calls take place in JSON format. JSON looks similar to a dictionary in python. Remember JSON is not a dictionary.
To handle the JSON python provides a builtin json
package. To use this package we need to import it as follows:
import json
This library provides two methods which help us in handling the JSON. Let's understand them one by one.
JSON loads:
If you have JSON string and want to convert it back to the dictionary you need to use a loads
método. Let's understand them by example. Go to the python shell and copy-paste the following code:
>>> import json
>>> json_string = '{ "user_name":"Sharvin", "age":1000}' #JSON String
>>> type(json_string)
>>> data = json.loads(json_string)
>>> type(data)
>>> data
{'user_name': 'Sharvin', 'age': 1000}
JSON dumps:
Now let's convert our data back to the JSON string format using the dumps
método.
>>> jsonString = json.dumps(data)
>>> type(jsonString)
>>> jsonString
'{"user_name": "Sharvin", "age": 1000}'
To know more about JSON Manipulation go through the Python's Documentation.
And we're done! I hope you have completely understood python from basics and a very big congratulations to you on this achievement.
Feedbacks are welcomed. Also if you want to learn about any topic you can tweet the topic name on twitter and include my twitter handle.[[[[@sharvinshah26 ]