Transcrições
1. Apresentação: Olá, pessoal. Bem-vindo ao
curso definitivo de programação em Python sobre compartilhamento de habilidades Neste curso abrangente, você mergulhará profundamente no Python,
dominando tudo, desde os fundamentos
até a programação avançada orientada a objetos Neste curso, você não
apenas aprende Python do básico à avançada programação orientada a
objetos, mas também descobre
como trabalhar com ambientes
virtuais e gerenciar várias versões do Você aprenderá como
alternar entre versões e lidar com várias
bibliotecas de forma eficiente. Essas são
habilidades cruciais para trabalhar em projetos do mundo
real, nos
quais a capacidade de
trabalhar com diferentes versões do
Python e suas respectivas bibliotecas geralmente
é necessária Eu acredito em fornecer
conhecimento valioso sem exageros. Cada aula é concisa e repleta de informações
essenciais, ajudando você a aprender de forma eficaz e com foco na
experiência prática Neste projeto, criaremos um aplicativo
gerador de código QR totalmente funcional que pode criar códigos QR para
seus perfis de mídia social Você aprenderá a
usar bibliotecas Python, trabalhar com módulos e
implementar estruturas de dados importantes Permita-me mostrar por que
mergulhar no Python agora pode ser um divisor de águas para sua carreira e De acordo com análises recentes do mercado de
trabalho, Python está consistentemente classificado entre
as principais
linguagens de programação em demanda Isso se traduz em
inúmeras oportunidades de emprego e estabilidade na carreira
para desenvolvedores de Python O conhecimento do Python também
pode abrir portas para funções
especializadas de alta remuneração,
como cientistas de dados, engenheiros
de aprendizado de máquina
e especialistas em IA Python é a melhor linguagem
para iniciantes. Sua sintaxe é clara
e direta, permitindo que
os programadores a aprendam rapidamente e se concentrem em aprender conceitos de
programação, em vez ficarem atolados em regras Investir seu tempo
aprendendo Python hoje é um investimento em seu futuro.
Não espere mais. Inscreva-se agora e comece sua jornada para se tornar um programador
habilidoso em Python Vamos descobrir o poder
da codificação juntos.
2. Instalação do Python: E primeiro, vamos verificar se Python já está
instalado no seu sistema Se você tiver o Windows, poderá fazer isso
pressionando Wind plus R, digitando CMD
e pressionando Enter Na janela do prompt de comando, digite o seguinte
comando e pressione Enter. E aqui estamos,
podemos ver nosso Python. No macOS e no Linux, também
abrimos a janela do terminal digitamos o seguinte comando
e pressionamos Enter Não preste atenção em todas
essas versões do Python. Falaremos sobre isso mais tarde.
Como podemos ver, eu não tenho a versão Python do
comando,
mas tenho a versão três do Command
Python Os comandos Python version e
Python three version
são usados para verificar a versão do interpretador
Python instalado Python Versão do Python, o comando tradicionalmente usado para verificar a versão
do Python dois, enquanto Python três é usada
especificamente para verificar a versão do interpretador do tradicionalmente usado para verificar a versão
do Python dois, enquanto a versão do
Python três é usada
especificamente para verificar a versão do interpretador do
Python três. Normalmente, o Python 2 era
usado em sistemas mais antigos. Se preferir, você pode ajustar configuração do
sistema para
fazer com que o Python aponte para o
Python três Mas eu prefiro continuar com o comando Python three porque
ele é comumente Se você não tiver nenhum Python
em seu sistema operacional, acessaremos o site
python.org e seguiremos as site
python.org Aqui você escolhe seu sistema
operacional e escolhe a versão
do Python que você precisa Eu trabalho no macOS e no Linux, mas instalar o Python no Windows não é
muito mais difícil Você baixa a
versão do Python, abre
o arquivo de download e segue as instruções de
instalação Aqui podemos baixar o
Python para Linux. Se formos ao Python, guia do usuário de empacotamento do
Python ,
e aqui eu escolho
tutoriais e, em seguida, escolho tutoriais Podemos ver muitas informações sobre como verificar a versão do Python e também como instalar Python em E aqui você pode notar que podemos instalar o Python de
maneiras diferentes Por exemplo, aqui podemos ver
os comandos que podemos usar para instalar o Python em um
Bunto ou, se usarmos Macs,
podemos usar o podemos Homebrew é um gerenciador de pacotes. Você pode ler mais em seu site. Com esse gerenciador de pacotes, podemos instalar o Python
usando esse comando Mas qual a diferença?
Bem, em breve, a pasta, Homebrew e o instalador oficial usarão as diferentes pastas
para instalação Também atualizando. O Homebrew atualiza
facilmente o Python para a versão mais recente com um único
comando Brew upgrade Homebrew também
gerencia dependências e
limpa automaticamente as versões antigas. Enquanto
instalador oficial para atualizar, você precisa
baixar manualmente a nova versão do site e passar pelo
processo de instalação novamente. A instalação por meio
do instalador oficial é mais independente, o que pode ser útil
em determinados cenários, mas pode tornar o gerenciamento de
dependências e ferramentas adicionais
mais complicado E geralmente adiciona ícones de
aplicativos na pasta de aplicativos. Se eu quiser ver todas as versões do
Python, instalei com o comando
Brew install Python, posso usar o Command Brew
List Python imediatamente todas as
pastas
e todas as versões do Python que tenho pastas
e todas Além disso, quero observar
que a instalação do uni com Home Brew é
simples com um único comando Brew
Uni Install Python, que remove completamente versão
instalada
do Embora a
desinstalação oficial do instalador seja mais complexa e exija a movimentação manual
de arquivos de vários diretórios Quanto a mim, o Homebrew é mais conveniente para
desenvolvedores e para aqueles que trabalham
frequentemente com Python e outras ferramentas por meio instalador oficial pode ser
adequado para usuários que preferem interferência
mínima no sistema e precisam instalar o Python
uma vez para necessidades específicas, e não planejam
atualizar ou gerenciar
várias versões com frequência atualizar ou gerenciar
várias versões A mesma coisa se usarmos
Linux, Ubuntu, qualquer coisa,
podemos usar o Sudo Ogat para instalar o Python ou podemos instalar o
Python ou podemos instalar o
Python No primeiro caso, esse é o método mais simples de
instalar o Python, mas você só pode instalar
versões do Python que estejam disponíveis nos Instalando a partir do código-fonte, você pode usar qualquer versão do Python,
incluindo as versões mais recentes Agora que entendemos
como instalar o Python e a diferença
entre os métodos de
instalação,
vamos continuar aprendendo o
Python em Eu abro o terminal e digito
o comando Python. Um dos recursos exclusivos do Python
é o modo interativo, que permite executar código e ver imediatamente os resultados Isso é possível graças
ao interpretador Python, um programa que lê e
executa Quando você instala o Python
no seu computador, ele inclui um
intérprete interativo conhecido como apple Redesenvolva o ciclo atual. Ele permite que você insira o código uma linha por vez e
veja o resultado instantaneamente. Ao usar o modo interativo, você pode experimentar rapidamente diferentes trechos de código e
ver o resultado Para sair do modo interativo, use o comando exit. Bem, vimos o
modo interativo no terminal, mas também temos
várias ferramentas que nos
ajudam a escrever código com
mais eficiência. Vamos dar uma olhada neles.
3. Configuração: instalação de editores de código: Bem vindo de volta. Na lição
anterior, descobrimos o
modo interativo em que podemos executar código e
ver imediatamente os resultados no terminal. Hoje, veremos
as ferramentas que tornam codificação mais fácil e
eficiente Três dos editores de código mais
usados são Pycharm, Visual Studio code
e Jupiter Qual deles você
escolherá, depende de você. O primeiro, Pycharm. Existem várias opções
comunitárias e profissionais. Essa ideia
foi projetada especificamente para Python, mas você também pode usar
outras É como uma caixa de ferramentas
para desenvolvedores de Python. Você pode baixar
Biharm Community. É totalmente gratuito
e, para ser sincero, é o suficiente pela primeira vez. O processo de instalação
não leva muito tempo. Fazemos o download do arquivo e
seguimos as instruções. Existem muitos recursos,
como ferramentas de depuração, gerenciamento de
projetos e sugestões gerenciamento de
projetos Muito útil. É melhor para projetos
maiores,
nos quais você precisa manter tudo
organizado e eficiente. Então, temos o código do Visual Studio. É um editor de
código leve que suporta muitas
linguagens de programação, incluindo Python Depois de baixar o arquivo, abra-o clicando duas vezes nele. Isso extrairá o aplicativo de código do Visual
Studio. Arraste o aplicativo de
código do Visual Studio para a pasta do aplicativo e aqui estamos, isso
instala o código VS no seu mac Aqui você pode criar um
arquivo, abrir uma pasta
ou visualizar
arquivos abertos recentemente, ou visualizar
arquivos abertos recentemente aqui podemos
ver várias guias. Nenhuma pasta aberta. A guia aparece quando você não
abre uma pasta para o espaço de trabalho Ele solicita que você abra uma pasta para começar a
trabalhar em um projeto Depois de abrir uma pasta, a guia desaparece e os arquivos na
pasta são exibidos guia Abrir editor mostra uma lista de todos os arquivos
que você abriu atualmente no editor. Aqui podemos criar um novo
arquivo do zero. A guia de tópicos fornece uma visão estruturada,
como funções, variáveis e classes no arquivo aberto
no momento Ele ajuda você a
navegar rapidamente pelo
código pulando para
diferentes partes do arquivo Se quiser, você também
pode ocultar essas guias. É perfeito se você estiver
trabalhando em diferentes tipos de projeto e quiser um editor flexível
e completo. É muito fácil de instalar
e muito fácil de usar. Então temos o caderno Judi. É uma ferramenta baseada na web. Você pode usá-lo para pesquisa e
ciência de dados. Ele permite que você escreva e
execute código em pequenos pedaços, e você pode
ver imediatamente os resultados Parece um modo interativo, exceto que essa ferramenta é
ótima para criar documentos
interativos
que combinam código, texto e visualização Notebook Jupiter, você pode
instalar maneiras diferentes. Instalando Júpiter
usando Anaconda e
Conda ou Você pode instalar o Jupiter com gerenciador de pacotes
PIP se
optar por usar o Anaconda, para que ele instale o Python
e o Jupiter Notebook e
outros endereços de tag comumente usados para computação e ciência o gerenciador de pacotes
PIP se
optar por usar o Anaconda, para
que ele instale o Python
e o Jupiter Notebook e
outros endereços de tag comumente usados para computação e ciência de dados específicas. Então você tem tudo em
um, mas para começar, você pode gerenciar com o notebook
Jazz Jupiter instalando-o usando o PIP Você pode usar o que quiser. Depende de você. Neste curso, usarei o código do Visual Studio. Bem, depois de toda
essa preparação, vamos começar a escrever o código.
Nos vemos na próxima aula.
4. Como gerenciar versões do Python: ambientes virtuais e Pyenv: Muitas vezes, na realidade, você terá que trabalhar com
várias versões do Python Isso ocorre porque cada projeto tem sua própria pilha de tecnologia
e versões de pacote Para evitar bagunçar
seu computador de trabalho e lidar com conflitos entre
diferentes versões, é ideal usar um ambiente
virtual Não é urgentemente
necessário no momento, mas sugiro que você
entenda como funciona Isso vai te ajudar muito.
Você pode pular essa parte Isso não afetará seu
aprendizado dos conceitos básicos do Python. Isso será mais necessário quando você começar a
trabalhar em um projeto. E agora vamos começar. Pessoal, se você quiser gerenciar várias versões do Python
em sua máquina, existe uma ferramenta Ele permite que você alterne facilmente
entre várias versões do Python e altere versões
globais do Python Vamos começar
com o MacOS e depois mostrarei
como ele funciona no Ubuntu A primeira etapa que você
precisa dar antes de instalar qualquer coisa
nova é atualizar. E, por precaução, atualize
para atualizar todos os pacotes. O primeiro comando atualiza metadados do repositório
local,
o segundo comando, Brew upgrade,
atualiza todos os pacotes instalados em seu sistema para as versões
mais recentes disponíveis É uma prática comum que os usuários primeiro executem o
Brew update para obter metadados
mais recentes e, em seguida, executem Brew upgrade para atualizar
seus pacotes instalados Isso garante que o sistema tenha o
software mais recente instalado. Vamos ao Github e
seguimos as instruções. Em seguida, usamos o Brew
install para instalar o PMF. Basta copiar esse comando
e executá-lo. Vamos voltar à
documentação e ver o que precisamos fazer a seguir. Rolando para baixo, e aqui
estamos, eu uso Z SH ou shell. É um
shell de linha comum que serve como alternativa ao shell Boss, mais
conhecido. Então eu copio todo esse código
e posto no arquivo SHC. Então, instalamos o PNF e agora quero falar com você sobre o ambiente virtual O ambiente virtual
resolve um problema real. Você não precisa
se preocupar com os pacotes instalados no local
principal do sistema. O PynVirtonV é um plugin para
a ferramenta PNF que permite ao
usuário criar e gerenciar
ambientes virtuais para ambientes Com isso, você pode isolar as dependências
do projeto com
mais eficiência Então, novamente, siga
as instruções e instale este plugin. Após a instalação,
copiamos esse comando e o adicionamos ao arquivo SHRC Nesse caso, fazemos isso manualmente. Abra o arquivo HRC. É um arquivo oculto e normalmente está localizado no diretório inicial do
usuário. Eu uso o editor de
texto nano simples e fácil de usar. Você pode usar o VIM. Aqui podemos ver três
linhas de código que foram executadas quando o
PAN foi instalado. E pause esse comando aqui. Escrevo meu comentário para uma melhor compreensão
no futuro. Novamente, para o editor de texto nano, eu uso os comandos Control
O e control exit Isso me permite escrever e
sair do editor de texto. Você pode usar seu editor de texto
e executar seus comandos. Em seguida, reinicie
o shell com esse comando. E podemos usar essas ferramentas. Então, vamos verificar isso. Aqui
podemos ver uma pequena documentação com comandos para
PNP e PM Vertls No primeiro comando,
verificamos a versão da PN. Ele exibia a versão atualmente
ativa do Python, junto com informações
sobre como ela foi Por enquanto, eu não tenho nenhum. Se eu quiser listar agora todas as versões do
Python conhecidas pelo
PM, eu uso as versões do Command
Pimp E, por enquanto, eu não instalei nenhuma versão do Python com Se eu quiser ver a lista de versões do Python disponíveis
para instalação,
posso usar a lista de traços de instalação do Command
PM Então, vamos tentar instalar o
Python com PM. Para isso, usamos o
comando PM install
e, em seguida, especifico a
versão do Python Vou instalar
outra versão do Python para demonstrar como você pode trabalhar em ambientes
virtuais isolados
com diferentes versões do Python Agora, ao mesmo tempo,
você aprenderá como instalar e remover o
Python usando Se eu verificar agora as versões, veremos várias versões do
Python O Asterix indica que momento, estou em um ambiente
global do sistema, mas tenho
duas versões do Python que posso usar para
criar novos
ambientes virtuais para criar novos
ambientes virtuais Neste
sistema operacional, eu tenho globalmente, quero dizer, Python
versão 3.10 Eu disse globalmente porque,
para cada projeto, podemos ter suas próprias versões do
Python E agora, com esse comando, criarei o primeiro ambiente
virtual. Para o projeto de teste, eu uso o
comando Py Virtual ENF. Em seguida, escolho a
versão do Python e posso chamar meu ambiente
virtual, seja o que for que você decidir Vou chamá-lo de NF e
versão do Python. E agora, com o comando
PN virtual lens, posso ver a lista de todos os ambientes
virtuais existentes. Para ativar meu ambiente
virtual recém-criado, eu uso o comando PNF, activate
e, em seguida, nomeio meu
ambiente virtual V 3.90 Eu imediatamente posso
ver que estou nela. Se eu verificar a versão do
Python aqui, ela é 3.90, diferente da versão global
que testamos anteriormente Se você tiver vários ambientes
virtuais e quiser alternar entre eles, poderá executar o
comando PM, ativar e nomear outro ambiente
virtual, mesmo que você escreva agora em outro ambiente
virtual ativo. Agora, se instalarmos
algo aqui, ele permanecerá isolado do ambiente
global. Quaisquer pacotes ou
dependências instalados dentro do meu
ambiente virtual não
afetarão a
instalação do
Python em todo o sistema ou outros
ambientes virtuais que possamos criar Então, vamos instalar algo aqui. Que seja Júpiter. Eu vou até a documentação
e sigo as instruções. Júpiter é uma ferramenta
para execução de código. Eu escolho Júpiter, por exemplo, pode ser qualquer pacote
ou biblioteca que você quiser Agora, com o comando PIP freeze, posso ver todos os pacotes que foram instalados no
meu ambiente virtual PP é um
gerenciador de pacotes para Python. Agora vamos imaginar
que não precisamos mais
desse ambiente virtual. Como podemos excluí-lo. Primeiro, se estiver ativo, devemos desativá-lo com
o comando PM deactivate Em seguida, usamos o comando Virtual delete e nomeamos nosso ambiente virtual
que queremos excluir. Então, quando eu verifico o Pi
na lente virtual, não
vemos mais nosso
ambiente virtual. Ele foi excluído junto
com todos os pacotes e bibliotecas que instalamos
lá, coisa muito útil. Mas isso não significa que a versão do
Python que usamos nesse
ambiente virtual também tenha sido excluída Se verificarmos as versões do Python, ainda
podemos ver Eu adicionei antes outro, só para mostrar como podemos desinstalar
as versões do Python com BMP,
o comando, desinstalar e
depois a versão do Python e do Viola,
desinstalamos o
Python versão 3.9 desinstalamos Com essas ferramentas, é muito simples gerenciar diferentes versões do
Python Agora vamos instalá-lo em um
Bunto. Nós fazemos a mesma coisa. Vá para a página do Github e
siga as instruções. Aqui, eu escolhi o instalador
automático. E aqui eu copio esse
comando para instalação. Antes da instalação, eu uso
o comando pudo Ug update,
esse comando, gerenciando pacotes
do sistema, depois PSUDoug Por isso, atualizamos e atualizamos todos os pacotes
instalados em nosso sistema. Agora podemos instalar o PAMP Fast neste comando
que copiamos anteriormente Em seguida, volte para a primeira página, ou documentação, e copie
essas três linhas de código. Vamos escrevê-lo
no arquivo Bahar C. Também é um arquivo oculto. É muito parecido com o que
fizemos com o MACOS anteriormente. Se você não conseguiu instalar o
Tmp e recebeu um erro, certifique-se de instalar
todas as dependências do Python e ter o Gid Depois de tudo isso, reinicie o
shell com o comando e podemos usar essa ferramenta. Usamos aqui o mesmo comando que usamos anteriormente em macros Vamos instalar o Python 3.90. Aqui podemos ver nosso Python
instalado. Agora vamos criar um ambiente
virtual com base nessa versão do Python Nós o ativamos da
mesma forma que antes com o macOS com o comando, ativamos e nomeamos um ambiente
virtual Provavelmente você não
encontrará esse problema, mas tenho um
comportamento inconveniente no meu sistema No momento, não vejo que
estou em um ambiente virtual. Se eu verificar, posso ver
que nós o criamos. Então eu tive que adicionar essas poucas linhas de código no meu BachrcFle Em um Bundu, eu também
uso o editor de nanotexto. Esses comandos me permitem
escrever e executar a partir do BachrcFle Execute a fonte de comando BRC. É para execução
do script BRC na sessão atual do shell E enquanto consertávamos isso. momento, estamos em nosso ambiente
virtual
e, por dentro, temos a versão do Python que
foi usada para criação Então, pessoal, todos os comandos
e todas as próximas etapas, da mesma forma que fizemos anteriormente. Espero que esse conhecimento
ajude você a ver você
na próxima lição.
5. Explicação da sintaxe Python e diretrizes do PEP: Na comunidade Python, há uma
abordagem estabelecida para fazer mudanças Nenhuma alteração significativa é
feita sem a criação de um novo documento chamado aprimoramento
do Python PEP Os documentos PAP desempenham um papel crucial na comunidade
Python , servindo a
propósitos diferentes, dependendo do tópico Informações: eles fornecem informações
essenciais para principais desenvolvedores do Python e anunciam o lançamento
programado para o Python Padronização. Eles estabelecem diretrizes
de estilo de codificação, oferecem documentação e
fornecem outras recomendações Design, eles descrevem os
novos recursos ou funcionalidades propostos . Uma lista de todos os pbs propostos
está disponível em um
documento dinâmico e
continuamente atualizado chamado Pbzero Pap eight, o
PEP mais conhecido, é o guia de estilo para código
Python que descreve as
melhores práticas
para escrever código Python legível Também quero observar
que o Python três não
é compatível com versões anteriores do
Python O Python 2 foi
descontinuado de forma eficiente e
não é A comunidade Python fez transição
completa para o
Python três, que agora é o padrão Neste curso,
aprenderemos Python 3. Ao aprender Python, uma das primeiras coisas
a entender é sua sintaxe ou o
conjunto de regras que definem
como o código Python Posso observar que a sintaxe do Python é conhecida por sua simplicidade E vamos começar
do primeiro recuo para definir blocos de código indentação e o Python
são uma parte fundamental da sintaxe e servem para
definir a estrutura
e o fluxo do código Como muitas outras linguagens de
programação que usam chaves para
denotar blocos de código, o
Python depende da indentação para indicar quais Devemos saber que a indentação usa quatro espaços por nível de
recuo Aqui podemos ver, como
exemplo de função, as linhas mensagem e mensagem retorno são indentadas
sob o bloco surdo, tornando-as parte
da função de grade A instrução print
está fora
da função e, portanto, não
faz parte da função de grade. Misturar tabulações e espaços para indentação no mesmo arquivo
pode levar a pode levar Então, devemos usar apenas uma coisa. No entanto, em editores
como o VS code, existem mecanismos que podem impedir que esse erro
apareça imediatamente O código VIS geralmente corrige automaticamente
o recuo enquanto você digita. Ele pode substituir as guias por
espaços com base nas suas configurações, para que você não perceba o problema, a menos que as misture explicitamente. Mas você deve entender que próprio
Python ainda gerará um erro de indentação se a mistura ocorrer no mesmo bloco
de código durante a Vamos examinar alguns
novos conceitos de variável,
operação, operador e
expressão e concatenação Em Python, uma variável é
um objeto implementado como um local de memória nomeado que
pode conter vários valores nome de uma variável começa com
uma ou mais letras latinas e pode incluir
dígitos e sublinhados Além disso, nomes de variáveis em
Python são sensíveis à chave, por exemplo, nome, nome e nome são três variáveis
distintas As variáveis são atribuídas
usando o operador igual. Ele vincula um
nome de variável a um objeto. Uma operação é uma ação que precisa ser
executada em variáveis. Pode ser, por exemplo, adição, divisão,
subtração, etc. Um operador é um
símbolo ou objeto que executa uma operação e tem uma notação simbólica
familiar Você pode ver exemplos
na tela. Um operando é um objeto,
por exemplo, um número, uma caracteres ou uma variável em que o operador
executa uma operação E temos a expressão que
é uma combinação de operações realizadas por
operadores em operanos Aqui vemos um exemplo de expressão em que a adição
é a operação, mais o operador e a idade
e dois são os operantes Congatenação é
a operação de unir caracteres
ou conjuntos de Isso pode ser feito com o operador
plus. E também, isso pode ser feito com o operador de
multiplicação. Como eu disse antes, o
web eight fornece diretrizes sobre como escrever código
Python de forma limpa
e legível E aqui temos algumas regras. comprimento máximo da linha limita todas as linhas a um máximo
de 79 caracteres. Linhas em branco e
Python são usados para tornar seu código mais
legível Eles não são estritamente exigidos
pelo interpretador do Python, mas são úteis para as
pessoas que leem Isso ajuda a dividir seu código em partes
lógicas, como separar definições de
funções
ou separar de código que
fazem Portanto, temos regras básicas de
acordo com a página oito. Duas linhas em branco entre código de nível
superior, como funções
ou definições de classe, facilitam
ver onde uma função ou classe termina
e outra começa. E uma linha em branco
dentro das funções ou métodos para separar as seções
lógicas do código. Commons permite que você
explique o que seu código faz, tornando mais fácil para
os outros e para você, é
claro, entender a
lógica e o propósito por trás dele Os comandos do padrão I não são
executados pelo intérprete, então eles não afetam o
desempenho do seu código Eles são para leitores humanos. Temos comandos de linha única
e comandos de várias linhas. Os comandos de linha única começam
com o símbolo de hash. Eles são usados para
adicionar nós breves ou explicações sobre uma
linha ou bloco de código específico. Comandos de várias linhas podem ser
criados usando modos triplos. Para
uma explicação mais longa, forneça documentação para módulos,
classes e funções. Podemos usar
aspas duplas ou aspas simples. Ambos os tipos de aspas
triplas têm o mesmo propósito. A escolha entre
eles geralmente se resume à preferência de estilo pessoal ou
específica do projeto. Nomes claros e consistentes, ajude os outros e a si mesmo, entenda o
propósito das variáveis, funções, quaisquer que
sejam as classes. Portanto, temos a convenção de nomes. Convenção de nomenclatura,
use snake case para variáveis e funções
e Camo Ks E agora que
estamos familiarizados com os conceitos fundamentais e a sintaxe básica da linguagem, vamos começar a explorar objetos
Python
6. Tipos de dados numéricos em Python: int, float e complexo: Em Python, tudo
é um objeto. Vamos considerar a
criação de tipos de dados em Python. O primeiro tipo numérico. Eles incluem números inteiros que
representam números inteiros. Fluido que representa números
decimais e complexo representa números
complexos
com partes reais e imaginárias Vamos dar uma olhada em um
exemplo para ver como isso funciona. Em Python, números inteiros
são números inteiros que podem ser positivos,
negativos ou Eles são um
dos
tipos de dados mais básicos e comumente usados em Python Podemos verificar
exatamente o tipo de dados com a função de tipo. Aqui temos int. Em muitas linguagens de programação, números inteiros são limitados a um determinado intervalo,
dependendo do tamanho da
memória localizada Em Python, temos números inteiros
que podem crescer além desses limites e são limitados apenas pela
memória disponível, não por Isso significa que o
Python pode lidar com números inteiros
arbitrariamente grandes sem causar um Também podemos realizar facilmente operações
aritméticas Aqui podemos usar qualquer operador
aritmético. O único fator limitante é memória disponível da
sua máquina, não o Python Como podemos ver, essa flexibilidade
torna o Python especialmente útil para
operações matemáticas
envolvendo números muito grandes É muito útil em
aplicações em que a
precisão é fundamental. É uma tarefa comum
na programação quando você precisa trabalhar com dados de entrada
do usuário e, se eles
foram representados como string, você pode convertê-los em
números inteiros com a função It Agora podemos ver que
temos uma string. Usamos o tipo de função e aqui estamos, é uma string. Mas precisamos de um número inteiro, então usamos a função Int E se agora verificarmos o tipo, podemos ver que temos um número inteiro É claro que nem
sempre podemos fazer isso. Ao converter uma string, verdade string, em um número, você geralmente verá
uma mensagem de erro Vamos continuar com o float. O tipo de dados de fluxo
em Python representa números
reais com uma
parte fracionária ou É usado para lidar com números
decimais ou números
que exigem mais
precisão do que números inteiros Aqui também temos flutuações positivas
ou negativas. Também podemos notar que números
flutuantes podem ser expressos
usando notação científica, que é útil para representar muito grandes ou pequenos Também podemos realizar todas as operações aritméticas
básicas,
multiplicação, divisão Os flutuadores têm precisão de cerca de
15 a 16 casas decimais. Além disso,
erros de arredondamento podem ocorrer devido
à forma como os números de ponto flutuante
são armazenados na memória Os números de ponto flutuante são
representados de uma forma que
às vezes pode levar a pequenos erros
de precisão. Eu mostro o que quero dizer. Isso acontece porque os números de ponto
flutuante são armazenados em formato binário e nem todas as frações decimais podem ser
representadas com precisão em Como resultado,
podemos ver assim. Quando trabalhamos com laboratórios
financeiros, isso pode levar a erros graves,
então, como podemos resolvê-los. Temos módulo decimal
e padrão para isso. Ele ajuda você a trabalhar com números
decimais com precisão
arbitrária, evitando esses erros de
arredondamento binário Então, se eu realmente precisar de precisão, devo usar o módulo decimal Você pode me perguntar por que estou
usando aspas aqui. Porque quando você cria um objeto
decimal a partir de um float, Bthon primeiro converte o float
em uma representação
binária aproximada, o em uma representação
binária aproximada, que pode introduzir
imprecisões. O uso de
uma string garante que o
decimal interprete o número exatamente como você o escreveu, sem
a etapa intermediária o
Bthon primeiro converte o float
em uma representação
binária aproximada, o
que pode introduzir
imprecisões. O uso de
uma string garante que o
decimal interprete o número exatamente como você o escreveu, sem
a etapa intermediária. Isso evita
erros ao redor ou problemas de precisão. Caso tenhamos uma
variável inteira e outra seja flutuante E se dividirmos uma
variável por float, o resultado será do
tipo float em Python, quando você realizar operações
aritméticas o resultado será do
tipo float em Python,
quando você realizar operações
aritméticas envolvendo diferentes tipos de números. O Python converte
implicitamente os tipos para garantir que a operação possa ser executada
com
a Isso é conhecido como coerção de tipo. A função e o
padrão redondo são usados para arredondar o número de ponto flutuante para um número especificado
de casas decimais Por exemplo, temos
um resultado como esse e eu quero me livrar do dígito extra após
os pontos decimais Usamos a função redonda
e colocamos aqui o primeiro número. Queremos arredondar o segundo argumento,
e isso é opcional. Colocamos o número
de casas decimais para as quais você deseja
arredondar o número Se esse parâmetro for omitido, função arredondará para
o número inteiro Vamos continuar com os números
complexos, que consistem em duas partes, parte
real e uma parte imaginária Em Python, temos parte
imaginária indicada
usando o sufixo J.
Em outra linguagem de programação,
você pode, então I é Em outra linguagem de programação,
você pode, então I Então, aqui vemos um exemplo
em que três é uma parte real. E quatro J é parte imaginária. Temos várias funções de
construção para trabalhar com números complexos. E aqui vemos exemplo em que eu quero
mostrar a primeira parte real e depois a saída como parte
imaginária Em números complexos, também
podemos usar operações
aritméticas
como adição, subtração Por que e quando devemos usá-lo. Bem, números complexos são essenciais para áreas
como física, engenharia e processamento de
sinais. Na próxima lição,
consideraremos string, list, double e range.
7. Tipos de dados primitivos e de referência em Python: Em Python, todos os objetos
podem ser amplamente categorizados em objetos de referência e
objetos Os objetos de referência não mantêm
diretamente o valor, mas fazem referência ou apontam
para outros objetos que o fazem. Eles incluem listas, dicionários e
objetos personalizados relacionados às classes Esses objetos podem conter
vários outros objetos, que podem ser de tipos diferentes. Objetos atômicos são básicos. Objetos indivisíveis que
possuem um único valor. Esses são os
tipos mais simples de objetos em Python,
como números inteiros, flutuantes,
strings Eles não fazem referência a
outros objetos e são os
blocos de construção deles. Ao atribuir objetos atômicos, seu valor é copiado, enquanto que para objetos de referência, somente o ponteiro para
o objeto Como resultado, ambas as variáveis após a atribuição se
referem ao mesmo valor Vamos dar uma olhada em um
exemplo para ver como isso funciona. Por exemplo, criei um objeto
atômico, inteiro, e aqui atribuí meu
objeto a outro valor, depois imprimi, depois
altero o valor de A, deixe B seis E se imprimirmos os dois, podemos ver a diferença. Quando você atribui um
objeto atômico como um número inteiro, é feita
uma cópia do valor As alterações na variável original não afetam a nova variável. Vamos considerar o objeto de referência. Eu criei
um objeto de referência, uma lista. Então eu crio a variável Y, e ela recebeu
a referência à lista que
criamos anteriormente. Eu imprimo todas as duas variáveis. Então eu modifico a lista. Eu explico rapidamente na lista
Python que existem
coleções ordenadas que armazenam vários itens em
uma única variável O primeiro elemento da lista é atribuído usando o índice zero, o segundo elemento com
o índice um e assim por diante. Pego o primeiro elemento
e o atribuí a dez. Se eu imprimir as duas listas, podemos ver o mesmo resultado. Quando modificamos a lista por meio de X, a alteração também é
refletida em Y porque X e Y apontam
para a mesma lista na memória. Então, quando você atribui um objeto de
referência, como uma lista, as duas variáveis se referem
ao mesmo objeto. Alterações no objeto por meio uma variável também afetam a
outra variável, e você deve ter cuidado
e sempre se lembrar delas. Os objetos de referência podem ser
mutáveis ou imutáveis. O objeto mutável pode
ser alterado no local. As modificações não exigem a
criação de um novo objeto. Isso significa que você pode alterar, adicionar ou remover elementos ou valores sem
criar um novo objeto
e, é claro, as alterações no
objeto imutável serão refletidas em todas as
referências a esse Vimos isso muito claramente
no exemplo anterior, quando usamos list
e alteramos o primeiro valor,
listas, dicionários, conjuntos e objetos definidos pelo
usuário quando o
atributo pode ser Esses são todos objetos mutáveis. Objetos imutáveis não podem ser modificados após serem criados Se você quiser alterar
seu conteúdo, isso resultará
na criação de um novo objeto em vez de
modificar o existente Temos números inteiros, floyd, números
complexos, tapo,
string e bytes Como exemplo, criei um objeto
imutável como a explicação
Taple Quick Um tapo e Python uma coleção ordenada e
imutável Exploraremos
todos os tipos de dados com
mais detalhes posteriormente
neste curso. Agora eu pego o elemento do Taple com índice zero, e esse elemento
é o número um, e estou tentando substituir o número um
pelo número dez Se eu tentar modificar essa tupla,
receberei um erro. Só consigo criar um novo
com conteúdos diferentes, mas nem sempre
você tem um erro. Às vezes, pode parecer
que você mudou o
objeto, mas não mudou. Por exemplo, eu crio um objeto
imutável, uma string, e depois vou
transformá-lo em
letras maiúsculas à primeira vista,
é o mesmo, mas não é método Upper não modifica a string A original porque as
strings são imutáveis, como lembramos em Python Em vez disso, ele retorna uma
string em maiúsculas. Podemos verificar isso com o ID. Imprimimos o ID original
e, em seguida, chamamos o método
upper e depois imprimimos o ID por método. Então, podemos ver que essas duas
variáveis A são variáveis totalmente
diferentes. A função ID retorna
o identificador exclusivo, endereço de
memória de um objeto. Os endereços de memória de
A no primeiro caso e A no
segundo caso não são iguais. Isso confirma que eles não
são o mesmo objeto, embora
tenham o mesmo valor
8. Trabalhando com strings em Python: Bem vindo de volta.
Continuamos com o tipo de dados e agora
consideraremos E aqui temos uma string que representa uma sequência
de caracteres. Last representa uma
bela coleção ordenada de itens. Tapal representa uma coleção
ordenada imutável, como
lembramos Também temos range como um tipo de
sequência em Python. Ele representa uma sequência
imutável de números e é usada para Então, vamos começar com o tipo de dados de
string. Como eu disse antes, string é uma sequência de caracteres
entre aspas Podem ser letras, números, símbolos e espaços. Esse é o tipo de dados mais comumente
usado na programação. A maneira mais comum
de definir string é usando bodes simples
ou duplos Já vimos nas
aulas anteriores como podemos fazer isso. As aspas simples e duplas funcionam da mesma maneira
para a maioria das strings. Códigos triplos geralmente são
usados para cadeias de várias linhas. E, como lembramos, string é um tipo de dados imutável Isso significa que, se
você criar uma string, não
poderá alterar seu conteúdo. A única coisa que você pode fazer é reatribuir a
variável a uma nova string, mas a string original
permanece inalterada E vimos isso claramente
na lição anterior onde aprendemos tipos de dados mutáveis
e imutáveis Portanto, cada caractere em uma string tem uma posição
chamada índice, que começa do zero. Você pode acessar caracteres
individuais usando esses números de índice. Podemos pegar o primeiro elemento, seja N. Vamos pegar
N ou K, mas não apenas indexação positiva, também
temos indexação negativa Podemos pegar o último caractere
usando o índice menos um ou o penúltimo
caractere e usar o índice
menos dois e assim por diante Também podemos usar o corte. Podemos extrair uma
parte de uma string. Usamos a sintaxe
em que iniciamos é o índice a partir do qual você começa e paramos o índice onde
a fatia termina, mas ela não está incluída
no resultado Se quiser começar do
início ou ir até o fim, você pode omitir os índices de início
ou parada Se você tentar acessar um índice
em uma string que não existe, Python gerará
um erro de índice Isso indica que o
índice está fora do intervalo. Mas se você estiver usando o fatiamento, o
Python Python Digamos assim. Isso não gerará um erro. Em vez disso, ele retornará o
máximo possível da
string. Ou uma sequência vazia se as fatias estiverem totalmente
fora do alcance. Então, vamos falar um pouco com esses
métodos desse tipo de dados. Podemos mudar o caso
da string com esses dois métodos,
inferior e superior. O primeiro converte
todos os caracteres em
minúsculas e o método maiúsculo converte todos os Para remover
espaços em branco de uma string no início e
do espaço final no final, podemos usar o método strip Também podemos remover caracteres
específicos passando-os como argumento. Por exemplo, aqui, eu quero
remover o ponto de exclamação. O método replace permite
substituir partes de uma string
por outra string. Isso é muito útil quando você precisa modificar
partes específicas da string Por exemplo, aqui, eu
substituí o Java pelo Python. Vamos imaginar que precisamos encontrar índice da primeira
ocorrência da substring E para isso, temos dois
métodos, encontrar e indexar. Ambos são usados para encontrar
a posição da
substring em uma string A primeira descoberta retorna o índice da
primeira ocorrência
da substring ou menos um se
a substring não for O índice faz o mesmo, mas gera um erro se a
substring não for encontrada Se precisarmos dividir
uma string em partes ou unir uma lista de strings
em uma única string, podemos usar funções divididas ou
unidas função Split
divide uma string em uma lista com base em um delimitador Podemos escolher o que quisermos. O padrão é espaço, mas também
podemos especificar um
delimitador diferente Por exemplo, aqui, eu escolho
coma. Eu uso o método join, ele pega uma lista de
strings e as une em uma única string com
um delimitador especificado Nós também podemos escolher isso. E aqui temos string em vez de lista. Se precisarmos
verificar, por exemplo, extensões de
arquivo, URLs
ou outros padrões comuns, podemos usar os métodos start with
e end with Verificamos se uma string começa ou termina com uma substrings específica Temos verdade se realmente começa e cai se não for verdade. E sim, não começamos
nossa frase em Java. E nesse caso,
verificamos as extremidades da string
com um sufixo específico Como você pode ver, é necessária uma
correspondência exata. Então você precisa adicionar
um ponto de exclamação. Se precisarmos saber
quantos caracteres estão sendo usados em uma string, por exemplo, podemos
usar um método a. Podemos usá-lo para
validar a entrada do usuário. Vamos continuar com a formatação de
strings. Temos três métodos principais
para formatar strings. O estilo antigo usando porcentagem, o método de formatação mais recente
e a abordagem mais moderna, a
Fstring, introduzida no Python 36 Vamos começar com o estilo antigo, que usa o operador percentual. Neste exemplo, a pessoa S é
um espaço reservado para uma string
e a pessoa D é para um número inteiro Temos duas
posições e salários variáveis. Uma variável é uma string e a segunda é inteira Então, eu quero criar uma mensagem onde vou
usar essas duas variáveis. O resultado será uma mensagem
formatada como essa. É muito útil. Podemos
alterar a variável e nossa mensagem será
alterada automaticamente. Vamos continuar com a
nova formatação de estilo. Aqui temos o método de formatação. Foi introduzido
no Python 3. Esse método é mais flexível e legível do que a formatação de
estilo antigo Neste exemplo, as
chaves Carl são espaços reservados para valores e
o
método de formatação os preenche É mais flexível e legível do que usar símbolos
pessoais Finalmente, temos a string F, que foi introduzida
no Python Essa é a forma mais moderna
e recomendada formatar strings
porque é mais limpa, rápida e fácil de ler As strings F permitem que você incorpore expressões
diretamente
dentro das chaves Carly Não há necessidade de nenhuma chamada de método
adicional. Basta usar o prefixo F
e pronto. Esse método é mais rápido
e geralmente mais legível, especialmente para expressões
complexas Ao usar a string F
ou o método de formatação, você pode adicionar
tipos de formatação dentro dos espaços reservados para controlar
como os valores são exibidos Isso é útil para especificar coisas como o número
de casas decimais,
pudim, alinhamento Por exemplo, aqui
temos um alinhamento à esquerda, a string do nome dentro de um
campo de dez caracteres E aqui, alinhamos à direita o número inteiro da pontuação em um
campo de três caracteres E, claro, podemos mudar isso. Também podemos usar F. Isso significa formatar como um número de ponto
flutuante com duas casas decimais E, claro, você
pode mudar isso. Se o usarmos com vírgula, temos milhares de separadores Essas opções de formatação ajudam a tornar sua saída mais
legível e Também temos
caracteres de escape em string. Eles são usados para incluir caracteres
especiais em
cadeias de caracteres que, de outra forma,
seriam difíceis de
incluir diretamente Usar caracteres de escape
pode nos ajudar a adicionar nova barra invertida na guia de linha E também podemos usar códigos simples
e duplos dentro da string. Então, ficamos assim. Também podemos repetir uma string
um número específico de vezes
usando o operador Asterix Vou adicionar um espaço para
torná-lo mais legível. E, claro, a concatenação, vimos isso na
lição anterior Nos vemos na próxima aula.
9. Como entender o tipo de dados Lista em Python: Então, vamos continuar
aprendendo os tipos de sequência e continuaremos com a lista. Lista, é uma coleção de itens que podem armazenar vários valores em
uma única variável. Como tipo de dados, as listas
são ordenadas e mutáveis. Pode ser alterado e
permitir valores duplicados. Eles são definidos
usando colchetes e podem conter elementos de
qualquer tipo de dados, como números,
seqüências de caracteres, outras listas
ou Os elementos na lista
têm uma ordem definida. Após a criação da lista, você pode
modificar os elementos internos
e, como eu disse, em um valor, você pode armazenar elementos de
diferentes tipos de dados. Você pode acessar
elementos de uma lista usando seu índice,
começando do zero. Por exemplo, aqui, eu obtenho elemento com o Índice
dois da Lista um e elemento com o Índice dois da Lista dois ou deixo que seja o
elemento com o Índice um. As duas primeiras listas
foram feitas com colchetes. Você pode atribuir diretamente os
elementos dentro dos colchetes, separando-os por Mas também podemos criar
listas como essa. Podemos usar a
lista de funções para criar uma nova lista,
a lista de funções e a sequência de
argumentos Hello. Converte a string hello
na lista tratando cada caractere na string como um
elemento separado da lista
e, no final, obteremos hello
composto por cinco caracteres A lista de funções pega
cada caractere e cria uma lista em que
cada caractere é um elemento individual. Também podemos criar uma lista
com intervalo de funções. A função range gera
uma sequência de números, começando de zero
até, mas não incluindo, seja seis no nosso caso. Então, ao convertê-lo em
lista usando a função List, obtemos uma lista de números de 0 a 5 e também podemos
gerar uma sequência de números começando de menos dois e subindo
sem incluir Novamente, uma função de lista converte esse objeto de intervalo em uma lista e temos esse resultado Por padrão, a etapa é uma, o que significa que ela é
incrementada em uma em cada etapa Mas também podemos configurá-lo. Por exemplo, vamos
criar outra lista. Aqui eu uso o intervalo de funções. Isso gera uma sequência
começando de -30 até 50, incrementando em
dez em cada etapa Portanto, temos
o número -30 como ponto de partida e o segundo número 50
como ponto final,
mas o próprio 50 não está incluído E o terceiro número dez
especifica o tamanho da etapa, o que significa que a sequência
será incrementada Em Python, quando você usa o
operador plus com duas listas, ele as concatena, o que significa
que as une Vimos algo semelhante quando aprendemos o tipo de dados de string. Quando você multiplica uma
lista por um número inteiro, no nosso caso, seja dois No nosso caso, ele repete os elementos da
lista duas vezes. A lista original
não foi modificada. Em vez disso, a lista U é criada
com os elementos separados
e, claro, podemos
combiná-la com a concatenação Se quisermos adicionar um elemento
ao final da lista, podemos usar o método append Portanto, no nosso caso,
o método append adiciona o valor 33 no final
da lista O método append modifica diretamente
a lista original. Ele não retorna uma lista U. Ele atualiza o existente. Queremos excluir
o elemento com índice
definido na lista, podemos usar a declaração Dell. Ele modifica a lista existente
removendo o item
no índice especificado No nosso caso, excluímos um
elemento com índice três. No caso em que queremos
inserir um elemento em uma posição ou índice
específico, em uma lista, podemos
usar a função de inserção. primeiro argumento é
o índice em o novo elemento deve ser inserido e o
segundo argumento, deixe-o feliz
no elemento que será
inserido nesse índice. Caso desejemos remover
a primeira ocorrência do valor
especificado da lista, podemos usar o método remove, então
decidi remover happy, então coloquei isso como
argumento, e aqui estamos. Vamos também remover 4.23. Qual é a diferença
entre Dell e remove? O método Remove é usado para remover
um elemento por seu valor. Ele procura a
primeira ocorrência
do valor especificado e a
remove da lista. Se o valor não for encontrado, ele gerará um erro de valor A declaração Dell é usada
para remover um elemento
pelo índice ou para excluir totalmente
uma variável. Se não especificarmos nenhum índice, a lista inteira será excluída. Também temos o método pop. É para remover e retornar
um elemento de uma lista. Por padrão, ele remove e retorna o último
elemento da lista, mas você também pode
especificar um índice para remover e retornar um elemento
específico. Portanto, no nosso caso,
removemos e retornamos o último elemento da
nossa lista. Isso é 33. Como você pode ver, atribuo esse 33 a uma variável apenas para
imprimi-lo para ficar mais claro Em seguida, vou excluir
o elemento com o índice dois. No nosso caso, será olá. Se eu imprimir a lista agora, veremos claramente que
removemos o olá da nossa lista. Deixe-me remover o necessário, e vamos imprimir a lista seis. Também podemos usar aqui a técnica
de fatiamento. Por exemplo, aqui,
eu quero obter uma fatia do segundo
índice até o quatro, mas é claro que quatro não serão
incluídos em nosso resultado Ele retorna uma nova lista contendo os elementos
começando no Índice dois e terminando no índice
três ou seja seis. E obtemos a lista,
começamos com o Índice dois e terminamos com o Índice cinco. Neste exemplo, o slice extrai elementos do início até
a lista até, mas não incluindo o Índice seis Se a lista tiver
menos de seis elementos, ela retornará a lista inteira. Este exemplo
nos mostrará que a fatia começa no Índice dois e inclui todos os elementos
até o final da lista Também temos a função de lente. Em Python, usado para determinar
o número de itens em um objeto, como podemos
ver, ele retorna oito Isso significa que a lista
contém oito elementos. Deixe-me imprimir a lista novamente e vou
usar o método inverso. É usado para reverter os
elementos de uma lista no local. Isso significa que a ordem
dos elementos na lista
original é invertida e a
lista é modificada diretamente sem criar
uma nova lista. Portanto, tenha cuidado. Também podemos classificar os elementos de uma lista no local
usando o método sort. O método
organiza os elementos
da lista em
ordem crescente por padrão Esse não é um exemplo muito bom. Deixe-me
substituí-lo por pelo menos um. E faça alguns
ajustes para maior clareza. Então, aqui podemos ver claramente
que nossa lista foi ordenada. Mas se definirmos inverso
igual a verdadeiro,
a lista será classificada
em O valor padrão de reverse, é claro, cai
e podemos omiti-lo Caso desejemos remover todos os elementos da nossa lista, podemos usar o método clear. Esse método remove todos os
elementos da lista, resultando em um comprimento de zero. Esse método não
retorna nenhum valor. Ele executa a
operação de limpeza na
própria lista . Nos vemos
na próxima aula.
10. Explorando o tipo de dados tupla em Python: Bem-vindo de volta. Vamos continuar aprendendo
os tipos de dados do Python E agora vamos dar uma olhada em Taples. Taple é uma coleção de elementos imutáveis
ordenados
em Python É semelhante à Lista,
mas, ao contrário da Lista, não pode
ser alterada após a criação. E aqui usamos parênteses. Quando criamos uma taple, os elementos em uma tabela mantêm a ordem em que
foram definidos E uma vez criados, os elementos em uma taple não podem ser modificados O Tapos pode armazenar
diferentes tipos de dados. Por exemplo, aqui,
eu crio um Taple onde temos
inteiro e string Além disso, os elementos
podem ser repetidos. Podemos verificar se temos
tapo com a função de tipo, mas quero
observar que também
podemos criar um Taple
sem Eu removo os parênteses para mostrar que isso é conhecido
como embalagem Taple Quando você fornece vários
valores separados por vírgulas, Python os agrupa
automaticamente em Portanto, temos o mesmo resultado como se usássemos parênteses Também podemos criar uma taple com apenas um elemento. Ao criar uma taple com
apenas um elemento,
você precisa indicar
uma vírgula após
esse elemento para garantir que o Python o
reconheça Sem a vírgula, o
Python a interpreta
como um valor
regular entre parênteses, não como uma Se eu remover a vírgula, você verá que o
tipo foi alterado E, como podemos ver, temos apenas um número inteiro normal Mas se eu adicionar vírgula, teremos uma tabela novamente. Vou devolver tudo como estava e remover coisas
desnecessárias. Os elementos em uma
tabela podem ser acessados usando índices,
assim como listas Vamos pegar, por exemplo, o elemento com índice dois. E aqui também temos o corte. Aprendemos isso na lição
anterior. Começamos o índice em que
a fatia começa inclusiva e o índice em que a
fatia termina No primeiro exemplo,
recebi uma fatia. Eu extraio todos os elementos do Índice dois até o final da taple. Essa fatia extrai todos os elementos do início
da tupla até o Índice dois,
mas não incluindo o índice dois mas não incluindo Aqui temos uma fatia que extrai elementos
a partir do Índice um, até o Índice quatro, mas não inclui o
elemento no índice Isso significa começar no Índice
um e parar no Índice quatro. Aqui também temos índices
negativos para acessar elementos do final
da taúpla Como eu disse antes, as
tuplas são imutáveis, o que significa que você
não pode alterar ou remover elementos após
a criação da tupla Por exemplo, aqui, tento
alterar o elemento
com índice zero e recebo um erro. Eu crio um novo tapo. Eu queria te mostrar como
podemos concatenar dois
ou Podemos combinar os elementos
das taples em
uma única taple usando
o operador plus, e isso é concatenação, como Depois disso, temos um novo grampo. A ordem dos elementos no tapo concatenado é a
mesma que aparece nos Você pode repetir os elementos de um tapo usando o operador de
multiplicação. Por exemplo, aqui, pego a tabela B e uso o operador de
multiplicação e a repito três vezes Em Python, você pode verificar
se um elemento específico está presente em uma queda
usando o operador Isso é chamado de teste de
associação. O operador in retorna um valor
booleano verdadeiro se o elemento existir na
tupla ou falso se não Então, podemos ver claramente que existem
dois no Taple B, mas se eu escolher
22, obtemos false Se precisarmos retornar
o número de vezes que um valor especificado
aparece na tupla, podemos usar o método count Então, tentei contar as ocorrências de valor
três na queda B e obtive zero porque
não tenho três Mas se eu contar as
ocorrências do valor dois, tenho quatro, o que é verdade Vou aumentar um
pouco a queda só para
mostrar outro exemplo Para encontrar o índice
na primeira ocorrência
de um valor especificado, usamos o índice do método. Por exemplo, eu queria saber o índice de cinco
que acabamos de adicionar. Então eu tenho o índice, é quatro. Mas se eu tentar
descobrir o índice de elementos que não existe
, temos um erro. Para evitar manipular a expressão de erro de
valor, primeiro verifique o número de elementos usando o método count. Se for maior que zero, calcule a posição dos elementos usando o método de índice. Então eu verifiquei o
número de elementos. Temos um e agora posso verificar o índice porque tenho
certeza de que esse número existe. Por exemplo, podemos
usar a condição iLS. Examinaremos mais de perto essa construção um pouco mais tarde, mas explicarei brevemente que a construção
do ILS é uma declaração de fluxo de controle que
permite que seu programa
tome decisões e execute
determinados blocos de código com base nas condições. Na primeira condição, verificamos se a contagem do valor é
maior que zero
e, se for verdadeira, imprimimos o índice. O bloco s é opcional, mas será executado se a condição na instrução If
for falsa. Então, eu mudo de cinco para
15 para ficar falso e adicionarei um bloco. E lá dentro, eu imprimo a mensagem. Então, aqui podemos ver claramente
que a condição retorna falsa no primeiro
bloco de código e o código dentro do bloco
IV é ignorado É por isso que recebemos a mensagem do segundo bloco de código. Também pode verificar se o
valor cinco está presente no tapo usando
essa construção Portanto, se o valor for encontrado, o que é, o
código retornará verdadeiro. Portanto, o primeiro bloco
de código retorna verdadeiro e podemos obter seu índice. Mas se eu indicar o
número errado, recebemos a mensagem. Mas pessoal, vou chamar sua
atenção para o fato que
escrever diretamente um número
no bloco de condições não
é uma boa prática. A abordagem correta é
atribuir esse número a uma variável e depois
trabalhar com a variável. Vou remover esse estilo
codificado e, em vez disso, criar uma variável Usar uma variável como
item em nosso caso, em vez de codificação física, torna seu código mais flexível Como você pode ver, posso
alterar o valor da variável sem tocar
na real
do código AFLS Vamos dar uma
olhada na desembalagem. descompactação da taple permite que você
atribua elementos de uma taple
a várias variáveis Você pode empacotar e descompactar taples sem precisar de sintaxe extra, que torna o código
mais limpo Aqui, eu desempacoto o grampo em variáveis individuais
e as imprimo Nosso tapo é definido
com cinco elementos. Ele contém quatro
números inteiros e uma string. Eu atribuo os valores
do tapple a esse
grupo de variáveis, e isso funciona porque o
número de variáveis
no lado esquerdo corresponde
ao número de elementos
no taple Mas o que acontece se houver poucas ou muitas
variáveis, se o número de variáveis no lado esquerdo não corresponder ao número
de elementos no duplo, o Python gerará um erro Aqui temos um erro de valor, muitos valores para descompactar Isso ocorre porque a
descompactação da tabela exige que o número de variáveis e elementos
seja exatamente o mesmo Se quiser descompactar alguns
elementos, mas não todos, você pode usar o operador Asterix para capturar os Isso atribuirá
um à variável B. Olá, atribuímos à variável R, e o resto dos
elementos serão armazenados na variável E como uma lista. Se eu imprimir a variável E, veremos essa lista. Podemos obter o
número de elementos na fita usando a função de
comprimento Eu crio a variável B e atribuo o número de
elementos a essa variável
e, claro, depois a imprimo. Portanto, temos cinco elementos
no livro. Até a
próxima lição
11. Como entender o tipo de dados booleano em Python: Bem vindo de volta. Vamos dar uma
olhada nos tipos de dados booleanos Em Python, os booleanos são representados pelas
palavras-chave true Verdadeiro representa uma condição lógica
sim ou positiva, e falso representa uma condição lógica
não ou negativa. Vou dar exemplos com expressões que são
avaliadas como verdadeiras ou falsas, para que você possa entender. Mas primeiro, vamos considerar os operadores
booleanos. Operadores de comparação
usados para comparar valores e retornar verdadeiro ou falso. Aqui podemos ver que quatro é
igual a quatro, o que é verdade. Então, neste exemplo, podemos ver que três
não é igual a quatro, que também é verdade, e depois cinco a mais do que
um, e é Então, temos operadores lógicos em que combinamos expressões
booleanas Esses operadores são essenciais para controlar o
fluxo de programas. Temos três operadores booleanos, lógicos e lógicos
ou uma nota lógica O operador final retornará verdadeiro
se ambos os operandos forem verdadeiros. Se algum desses operandos for
falso, o resultado será falso. Podemos ver a tabela em que
temos duas condições
e, se duas condições forem verdadeiras, obtemos o resultado verdadeiro. Então, temos o mesmo com false. Se duas condições forem falsas, teremos um resultado falso. Já estamos familiarizados
com o bloco de código I, então vou usá-lo
neste exemplo. Temos a primeira condição se for maior que zero e
for maior que zero. No nosso caso, é verdade porque
os dois números são positivos. Como resultado, toda a
expressão é avaliada como verdadeira e recebemos a mensagem de que os dois números são positivos Caso a primeira
condição seja falsa, Paton não verifica
a segunda condição porque obteremos o valor
falso de qualquer maneira Então, temos o lógico ou
o operador or retorna verdadeiro se pelo menos um
dos operandos for verdadeiro Se ambas as condições forem
falsas, o resultado será falso. Portanto, neste exemplo, temos que todas as expressões são
avaliadas como verdadeiras porque
pelo menos um número é positivo. E aqui, se a primeira
condição for verdadeira, Biden avalia
a segunda condição porque seremos verdadeiros de qualquer maneira E então temos a lógica de não. O operador nod inverte o valor booleano
do Ele retorna verdadeiro se o
operando for falso e falso, o operando for verdadeiro, o operador nod
é frequentemente usado para
negar a condição Por exemplo, aqui
temos A igual a dez e tentamos verificar se
não A é igual a zero,
então é verdade, A não é Também podemos combinar operadores
lógicos. Você pode combinar vários operadores
lógicos para formar condições complexas. Usamos parênteses para
agrupar as condições e garantir a ordem correta da avaliação Então, no primeiro caso, temos verdade porque
A e B são positivos. Na segunda condição, se verificarmos se o C não é
igual a 15, obtemos falso Porque, na verdade, C é igual a 15. Como o operador or é usado, toda
a expressão é avaliada
como verdadeira. Vamos verificar isso. Aqui estamos, somos
verdadeiros porque, como podemos
ver na tabela, verdadeiro ou falso é verdadeiro. Vamos considerar a ordem dos
precedentes para operadores lógicos. Aqui você pode ver do
mais alto para o mais baixo. Em Python, quando vários operadores
lógicos são usados juntos
em uma expressão, ordem
dos
precedentes determina quais operadores são Isso é essencial
porque afeta
a forma como a expressão geral é interpretada e
seu resultado final O Knot tem os maiores precedentes
entre os operadores lógicos. Isso significa que quando você
usa not em uma expressão, Python avaliará
o operador not antes de qualquer outra coisa Então, temos a segunda
maior precedência, operador e a
segunda maior precedência Isso significa que em uma
expressão com operadores, por exemplo, e ou, mas depois avalia primeiro
a expressão e o operador ou tem
as menores precedências Aqui temos um exemplo.
Nada é avaliado primeiro B e C são avaliados a seguir. Aqui falso e verdadeiro
se tornam falsos. E, finalmente, falso ou falso é avaliado,
resultando em falso. Nos vemos na próxima aula.
12. Trabalhando com o tipo de dados do dicionário em Python: Bem vindo de volta. Vamos continuar com
o dicionário. Dictionary and Python é uma
coleção ordenada e mutável de itens Cada item é um par de valores-chave em que as chaves devem ser
exclusivas e imutáveis, e os valores podem ser de qualquer tipo de dado Podemos criar um dicionário
colocando os
pares de valores-chave entre chaves CRL. Cada par é
separado por uma vírgula, e a chave e o valor dentro de cada par são
separados por coluna Aqui temos as chaves, o nome, a idade, cidade
e os valores Alice, 30, e Nova York Além disso, podemos criar um dicionário
usando a função Dict. Isso é especialmente útil quando você deseja criar
um dicionário com tipos de dados
mais complexos ou
quando a chave não são cadeias Aqui temos um dicionário
usando o construtor dict. Você pode começar com
um dicionário vazio e adicionar o valor da chave Pars posteriormente. Por exemplo, aqui, eu
criei um dicionário vazio
e, em seguida, estou adicionando o
valor-chave Pars um por um E se eu imprimir o resultado, podemos ver que
preenchemos esse dicionário. A
maneira mais simples de acessar um valor em
um dicionário é usando sua
chave entre colchetes Neste exemplo, recupero o valor
associado ao nome da chave Mas também temos o método G. Ele permite que você acesse os valores do
dicionário, fornecendo uma maneira de lidar com situações em que uma
chave pode não existir. Esse método retorna conhecido
se a chave não for encontrada, evitando um erro de chave. Se eu usar para essas chaves, colchetes,
obtemos o erro Se quiser recuperar todas as chaves ou valores
em um dicionário, você pode usar os métodos de chaves
e valores Aqui podemos ver que o método
keys retorna todas as chaves e os valores do método retornam o objeto de
visualização exibindo
uma lista de todos os valores. Como eu disse antes, o dicionário
em Python é imutável. Isso significa que você pode alterar o conteúdo de um dicionário
após sua criação. Você pode adicionar, remover
ou atualizar valores, como adicionar novos valores que vimos antes quando eu preenchi um dicionário
totalmente vazio. Agora, quero mostrar
como adicionar vários
valores-chave por. Para isso, usarei
o método de atualização. Esse método usa outro dicionário ou iterável
de valor de chave pers, e atualizamos nosso dicionário
com esses novos dados, e aqui podemos ver que você também
pode atualizar o valor associado a uma chave
existente simplesmente atribuindo um novo
valor a essa Por exemplo, aqui, eu atualizo
uma idade de valor existente e a altero para 31. Agora vamos continuar com a exclusão. A declaração da Dell
permite que você exclua uma bolsa de valores-chave específica de um dicionário
fazendo referência à Por exemplo, aqui, eu removo a idade
de um par de valores-chave. Portanto, temos o dicionário
atualizado. Se eu tentar excluir uma chave que não existe, recebo um erro. Também temos o método pop. Ele remove o valor da chave par por chave e retorna o valor
associado à chave. Então, aqui eu uso o método pop. Eu especifiquei a cidade-chave. Eu imprimi o valor
que eu removi. E então nosso dicionário. E aqui podemos ver
que eu removi Chicago. Se a chave não existir, você poderá especificar o valor padrão a ser retornado em vez de
gerar um erro. Se eu tentar abrir uma chave
que não existe, posso evitar um erro
fornecendo o valor padrão. Por exemplo, aqui eu forneço
o valor padrão, não encontrado. Eu não tenho essas chaves, então não encontrei a saída. O método do item pop
remove e retorna o último
par de Kevalu inserido do dicionário Esse método é
particularmente útil quando você precisa limpar o
dicionário de forma incremental Aqui eu adiciono o novo item. Eu o chamo de último item
e, em seguida, vou
removê-lo com o método de item pop. Eu criei a nova
variável, último item, e atribuí meu dicionário onde removi o último
item com o método de item pop. Em seguida, imprimo o item removido e
meu dicionário depois disso. Portanto, vemos claramente que
removemos o último item adicionado. Se quiser remover todos os
itens do dicionário, você pode usar o método clear. Esse método esvazia
o dicionário mas o mantém na memória, e você pode usá-lo
para trabalhos futuros Depois de chamar
o método clear, o dicionário ficará vazio, mas ele ainda existe
e podemos usá-lo. O método items em
Python é usado para retornar um objeto de visualização que
exibe uma lista valores-chave
de dicionários como tuplas Se precisar
armazenar ou manipular os pares de valores-chave
fora do dicionário, você pode usar a função de lista Se eu verificar esse tipo, aqui eu tenho itens de ditado. Mas depois da
função de lista, obtive a lista. Ele converte nosso dicionário em uma lista de pares de valores-chave Eu imprimo o que tenho, e vemos a lista. Os itens em um dicionário
não têm uma ordem definida no Python 3.7 e os dicionários
posteriores mantêm a ordem de inserção, mas ainda são Cada chave no dicionário
deve ser exclusiva. Se você usar uma chave
que já existe, o novo valor substituirá
o valor anterior Podemos verificar a
presença da chave em um dicionário com o operador. Isso retornará verdadeiro se a chave existir no
dicionário e falso caso contrário. No primeiro exemplo, temos verdadeiro e imprimimos que
a chave existe, e no segundo exemplo, temos o falso,
também podemos verificar o
valor em um dicionário e fazemos da mesma maneira. Mas com o método values, ele pode ajudar você a
evitar sobrescrever valores
existentes em um dicionário antes de adicionar um par de valores-chave Assim, você pode verificar se a
chave ou o valor já existe. Se você precisar classificar o
dicionário por suas chaves, poderá usar a função classificada Ele retorna uma lista
de chaves classificadas, que você pode usar para
reordenar o Nos vemos na próxima aula.
13. Explorando tipos de dados de conjunto e congelados em Python: De volta. Muitas vezes temos situações em que precisamos lidar com grupos de elementos exclusivos com eficiência. E é aí que conjuntos e conjuntos
congelados são úteis. Set and Python é um tipo
de dados incorporado que permite armazenar uma coleção de elementos não ordenados e
exclusivos É muito útil para tarefas como eliminar
duplicatas de dados ou realizar operações
matemáticas como união e interseção Seus elementos mutáveis
podem ser adicionados ou removidos, e também podemos
criá-los de várias maneiras No primeiro caso, nós o
criamos com chaves Carla. E a segunda, criamos um conjunto
vazio com o construtor de
conjunto, se eu quiser adicionar um
único elemento a um conjunto, posso usar a função add Por exemplo, vamos
preencher esse conjunto vazio. Os elementos e o conjunto não têm a
posição ou o índice definidos. Isso significa que
você não pode acessar itens como fizemos
com listas ou tuplas E como eu disse antes, conjunto tem elementos únicos. O Set elimina automaticamente entradas
duplicadas. Se você tentar adicionar um elemento que já esteja
presente no conjunto, ele simplesmente será ignorado. Eu adiciono outro nome para tornar
nosso conjunto um pouco maior. Eu queria mostrar
como podemos remover um elemento
específico e usá-lo com a função remove. Aqui podemos ver que eu
removi o nome Nick. Se o elemento não for
encontrado, ele gerará um erro. Mas se quisermos
evitar o erro de chave, podemos usar a função discard E aqui podemos ver que se eu remover um
objeto existente, não temos nada. Mas se eu remover o nome Nik, teremos o mesmo resultado que
tivemos com a função de remoção. Também podemos usar o método clear para remover todos os
elementos do conjunto. Vamos considerar operações
matemáticas
como união, interseção
e diferença Para isso, criei dois conjuntos
e, no primeiro caso, combinamos elementos de dois
conjuntos, excluindo duplicatas Como podemos ver, três
foi duplicado, mas aqui não o vemos Temos elementos totalmente exclusivos. Ok, vamos considerar outro
exemplo, interseção. Eu recupero o elemento
comum aos dois conjuntos, e aqui temos três Vamos obter elementos presentes em um conjunto, mas não em outro. Aqui eu uso o sinal de menos. E temos um e dois, o que é verdade porque temos
um e dois no primeiro set, mas não temos
no segundo. E vamos considerar a diferença
simétrica. Eu recupero elementos que estão em qualquer um dos conjuntos
, mas não em ambos Então, aqui temos elementos únicos, mas como podemos ver sem três, porque os três estavam
presentes em ambos os conjuntos. Você também pode verificar se
existe um elemento em um conjunto usando
o operador in. Por exemplo, aqui eu
configurei e no bloco de
código com a instrução If, verifico se a
string hello existe no meu conjunto. E se for verdade,
recebemos essa mensagem. Vamos. E aqui
temos um conjunto congelado. É uma versão imutável do conjunto. Mas, apesar dessa imutabilidade, conjuntos
congelados ainda suportam muitas das mesmas operações Podemos criar conjuntos congelados usando o construtor de
conjuntos congelados, e eu posso passar qualquer objeto
terável como staple ou Por exemplo, vamos criar um conjunto
congelado a partir da lista. Aqui eu tenho uma lista simples, e então eu crio
com o construtor frozen set e passo
essa variável, minha lista E aqui eu imprimi
nosso conjunto congelado que obtive da lista. Também posso criar um novo conjunto
congelado a partir do conjunto. Então, primeiro, eu crio um conjunto simples e depois o pauso
no conjunto congelado Eu também posso criar um conjunto
congelado a partir de uma string. Como a string é iterável, você pode criá-la facilmente Como eu disse antes, o
conjunto congelado é imutável, então não podemos aplicar métodos
como adicionar, remover ou limpar Assim como os conjuntos, os
conjuntos congelados não são ordenados. Não temos uma
ordem específica de elementos
e não posso tirar elementos
específicos daqui, e não posso tirar elementos
específicos daqui como fizemos com list ou double,
mas os elementos são exclusivos, mas os elementos são exclusivos, então as duplicatas são
eliminadas automaticamente ao
criar um conjunto congelado Como você pode ver,
aqui temos dois, mas quando estou no meu conjunto congelado, eu tenho apenas um L. Mas
também podemos verificar se um elemento está presente em um
conjunto congelado usando os operadores in ou not in, como
fizemos com set. Por exemplo, aqui eu verifiquei se letra
H estava presente no meu conjunto
congelado e descobrimos. Eu mostro rapidamente as operações de conjuntos
congelados e começo da Union. Eu tenho dois
conjuntos congelados e depois de Union, tenho um conjunto congelado que contém todos os elementos exclusivos
de ambos os conjuntos congelados. Então eu uso a interseção. Para isso, adiciono elementos
aos dois conjuntos congelados. A interseção de dois conjuntos
congelados contém somente os elementos que estão
presentes nos dois conjuntos congelados A variação da diferença
retorna os elementos que estão presentes
no primeiro conjunto congelado, mas não no segundo. Com uma diferença simétrica, temos o resultado em que temos elementos que estão em
um conjunto ou outro, mas não em ambos,
temos os elementos exclusivos
um e dois
do primeiro conjunto congelado e
os elementos exclusivos cinco, seis do segundo conjunto congelado Em seguida, vou verificar
se todos os elementos do primeiro conjunto congelado
estão contidos
no segundo conjunto congelado
e se temos falsos. Eu mudo um pouco meu primeiro conjunto
congelado. Agora vou verificar
se o conjunto congelado dois contém todos os elementos
do conjunto congelado um. E, eventualmente, temos Dre. Se eu tiver
que verificar se dois conjuntos congelados não
têm elementos em comum. Eu posso usar o método de junção ISDs. Se eu verificar agora, obtivemos
um erro porque é óbvio
que temos elementos comuns. Eu mudo um pouco
meus conjuntos congelados. E nesse caso, nós nos tornamos verdadeiros. Portanto, consideramos dois
tipos de dados: conjunto e conjunto congelado, conjunto é uma coleção mutável
de elementos exclusivos, conjunto
congelado e uma
coleção imutável de Se estivermos falando
sobre desempenho, defina um pouco mais devagar para o
hashing porque é mutável,
congelado, defina um pouco
mais rápido devido à Nos vemos na próxima aula.
14. Trabalhando com tipos de sequência binária em Python: Bem-vindo de volta. Gente,
vocês são incríveis. Você fez um trabalho
incrível até agora. Continue com o excelente trabalho. Os
desafios mais empolgantes ainda estão por vir. Vamos continuar. Hoje, abordaremos os últimos tipos
de
dados incorporados e, em seguida,
passaremos para loops e declarações
condicionais Bem, tipos de sequência binária. Essas são estruturas de
dados especializadas projetadas para lidar com dados
binários. Eles são essenciais para
trabalhar com arquivos, interagir com hardware ou realizar
comunicações de rede e começam com bytes O tipo Bytes e o Python representam uma
sequência imutável de bytes,
com cada byte sendo um valor inteiro de com cada byte sendo Um objeto de bytes é
semelhante a uma string, mas é usado para
dados binários e não para texto. E, como eu disse, é imutável. Então, depois de criá-lo, seu conteúdo não pode ser alterado. Há várias maneiras de
criar um objeto de bytes. A primeira maneira de usar a notação B, aspas
simples ou aspas
duplas. Essa sintaxe é a mais comum
para criar objetos de bytes, especialmente ao trabalhar com
texto codificado Na segunda forma, podemos criar o objeto Bytes usando
o construtor Bytes, e eu passo aqui
a string hello, mas também tenho que especificar o argumento que codifica UTF A função bytes pode criar um objeto de bytes a partir de
vários tipos de dados. Mas quando o usamos
com uma string, precisamos especificar a codificação para que o
Python saiba como
converter cada caractere E a codificação UTF oito é uma
das formas mais comuns de
codificar Vou te mostrar como funciona. Se a string contiver caracteres
especiais, UTF oito codificará o
símbolo como vários bytes No meu caso, ele é
representado por dois bytes e outros caracteres seguem
de maneira semelhante. Os computadores armazenam dados
em formato binário,
portanto, qualquer texto ou
caractere precisa ser codificado em bytes para ser
armazenado ou processado na memória, e o UTFaight é um padrão
de
codificação versátil compatível padrão
de
codificação O que é aski? Este é o código padrão
americano para intercâmbio de
informações Temos um
padrão de codificação de caracteres que foi
originalmente desenvolvido para representar caracteres em inglês em computadores e outros dispositivos Portanto, se a string contiver
apenas caracteres ASCI, como eu disse,
letras em inglês, números, a representação da mordida será muito
semelhante à
do texto original com o prefixo B. para indicar
que agora são bytes Mas quando a string contém caracteres fora do intervalo ASCI
padrão, esses caracteres
serão representados por suas sequências UTF de
oito bytes correspondentes E aqui podemos ver isso claramente. Dessa forma, o código
fornece uma maneira de preencher
a lacuna entre texto legível por
humanos e dados
binários legíveis por máquina O ASCI desempenha um papel importante
na comunicação por e-mail. Os protocolos de e-mail usam texto ASCI para se comunicar entre servidores
de e-mail Essa também é a base
para muitos formatos de arquivo. Muitas linguagens de programação também usam ASCI para arquivos de código-fonte Geralmente é usado para manipular
strings e programação, principalmente para tarefas básicas de processamento de
strings Os valores ASCI
facilitam a comparação, classificação e execução de
aritmética em caracteres, além de serem amplamente usados em sistemas
embarcados para
comunicação
e sistemas
embarcados para Espero ter deixado isso claro para você. Também podemos criar
objetos de bits usando números inteiros. Quando você passa um único inteiro
para o construtor Bytes, ele cria um objeto Bytes preenchido
com bytes nulos e
o tamanho Neste exemplo, cinco produz uma sequência
de cinco bytes nulos Parece assim. Isso geralmente é usado em programação
de baixo nível. Se precisarmos de
representação binária da lista, também
podemos fazer isso. Quando eu chamo esse construtor, Python processa
cada inteiro na lista
e obtemos que o inteiro
um se torna o byte assim, o inteiro dois se torna o byte assim , e assim por
diante Eventualmente, temos
o objeto final, que é uma sequência de bytes. Isso é imutável e significa
que você não pode alterar bytes
individuais nesse objeto Apesar do fato de termos uma lista que poderia ter
sido alterada inicialmente. Os caracteres ASCI são
numerados de 0 a 127 e cada caractere
corresponde a um número exclusivo nesse intervalo Podemos ver aqui
ao lado da tabela, os primeiros 31 caracteres e
o 127º caractere 127º caractere Esses são personagens de controle. Eles não representam símbolos
escritos, mas temos
caracteres imprimíveis, representam
letras, números, pontuação e símbolos que você pode
ver e usar Deixe-me te mostrar. Quando você chama o Bytes Constructor e
passa aqui uma lista como essa, Python pega
esses números e cria um objeto Bytes que
representa uma sequência de bytes Se os valores na lista
estiverem no intervalo de 0 a 127, Bython
os interpretará como códigos ASCI
e, como resultado, para números
no intervalo de 32 a 126,
como eu disse antes, esses números correspondem Veremos na tela que o Python os mostra como personagens. E então, se eu imprimir o resultado, você pode ver a
representação da string hello. Convertemos os números inteiros em seus
caracteres correspondentes de
acordo com o padrão ASCI Números fora do intervalo da tabela
ASCI serão representados
como códigos hexadecimais Podemos verificar isso e
podemos ver claramente que 72 corresponde a H, 101 corresponde a E e assim por diante. Compreender e trabalhar
com Bytes e Python é crucial para a
programação de vários aplicativos e manipulação de
dados Quem sabe onde você
usará o Python? Ele pode ser útil
para manipulação de arquivos ou criptografia e segurança, ou você pode usá-lo para processamento de imagem e áudio ou programação de
rede Então, vamos considerar alguns
métodos para Bytes. Para converter Bytes novamente
na lista original de números, você pode usar a função de lista
no objeto Bytes. Essa função
retornará uma lista
dos números inteiros que foram usados para criar bits em
primeiro lugar Podemos obter uma fatia de
um objeto Bytes em Python. Por exemplo, aqui temos objeto
Bytes
da string hello. Por exemplo, eu quero morder
no índice um. Quando você acessa um
byte específico por seu índice, Python retorna o valor inteiro
correspondente do byte , que é seu código ASCI e
, no nosso caso, 101 corresponde a E. Mas quando obtenho uma
fatia do objeto Bytes
, como resultado,
tenho outro objeto Bytes , que Os objetos Slices of Bytes são amplamente usados na programação
para diversos fins. Por exemplo, talvez
precisemos extrair seções
específicas
dos dados para análise. Ou, por exemplo, se estivermos
processando arquivos de imagem, talvez
queiramos
extrair o cabeçalho ou sequências de bits
específicas que representem certas
propriedades da imagem Os bytes suportam a maioria dos métodos de
string. No entanto, algumas funções de string não funcionam corretamente
com os objetos de mordida. Por exemplo, a
função LN retorna o número de bytes que as strings
ocupam na memória, não o número de caracteres, como vimos quando
trabalhamos com Por exemplo, aqui eu
tenho o objeto Bytes, que será Hello, que
consiste em cinco caracteres Ask. Cada caractere em hello é representado por um único
byte em UTF oito Então eu tenho cinco. Mas como os caracteres não
são asci, eles ocuparão
mais de um byte cada Em UTF oito, cada
caractere em nossos novos dados é representado
por vários bytes Então, obtivemos o comprimento total da representação
da mordida,
12 bytes. Se precisarmos
transformá-lo novamente em strings
legíveis por humanos, podemos usar o método de decodificação
e, claro, especificar
UTF oito, novamente, indica que
queremos converter bytes de volta em uma string
usando a Então, vamos continuar com a matriz Bt. É um tipo de dados incorporado que representa uma
sequência imutável de bytes Cada elemento no bitário
é um número inteiro que varia 0 a 255 representando
um Ao contrário do tipo de mordidas,
que é imutável, bitary permite que você modifique bytes
individuais e ajuste o comprimento da sequência de mordidas
após Vamos criar um
objeto bitário vazio sem elementos, e podemos fazer isso
com esse construtor Se eu imprimi-lo, podemos ver Bary
vazio, também podemos
criar um Bary a partir de Neste exemplo, criei
uma matriz de bits codificando uma string em um formato de
codificação especificado, UTF Um Bary pode ser criado a partir de várias fontes
e é mutável Aqui estou criando uma matriz de bits a partir de uma lista de números inteiros em que cada inteiro representa
um valor de byte no intervalo de 0 a 255,
como eu disse antes, cada número corresponde ao ponto de caractere do Podemos criar uma matriz Bt a partir de
um objeto Bytes existente. Como a matriz Bt é mutável
e Bytes é imutável, isso permite criar uma versão modificável Essa abordagem é
muito útil quando você recebe dados
na forma de bytes, mas precisa
modificar seu conteúdo. Falando sobre
a modificação de conteúdo, você pode acessar ou modificar bytes
individuais pelo índice, assim como nas listas Você também pode extrair um intervalo de bytes usando a sintaxe de fatiamento. Portanto, estamos lidando com tipos de dados
mutáveis, para que possamos adicionar um único byte
ao final da matriz de bytes E para isso, eu uso
o método append. E, claro, o byte a ser acrescentado deve ser um número inteiro No meu caso, 33 é o
código ASCI para ponto de exclamação. No caso de adicionar vários
bytes de uma vez, podemos usar o método Extend. E aqui adicionamos mundo. Podemos concatenar um bitário com
outro bitário ou bytes É muito parecido com o
que fizemos com a corda. Vamos continuar com a
exclusão e a remoção. Você pode remover bytes por
índice usando o dell keod. Isso exclui a mordida
na posição específica. E no meu caso, eu
excluo o byte com Índice dois ou deixo que
seja o índice um Para remover e transformar o último byte ou bit
em uma posição específica, eu uso o método pop
e já sabemos que 111 corresponde
a O na tabela ASCI Também podemos especificar um índice. Nesse caso,
removemos o Android turn and the bite com o índice 101. Para obter o índice
da primeira ocorrência de uma sequência de bytes
em uma matriz de bytes, posso usar o método find Aqui temos o índice inicial
do mundo e a data seis. Se você precisar converter
a matriz Bt de volta em um objeto de bytes
imutável, podemos usar um construtor de bytes Por exemplo, aqui
eu tenho uma matriz Bt, mas depois decidi
torná-la um dado imutável Então eu uso os bytes do construtor. E aqui estamos quando você
trabalha com bytes, mas depois deseja exibir ou processar posteriormente
os dados como um texto, pode decodificá-los e
usá-los para esse método de decodificação Isso converte o bitário
novamente em uma string. Aqui está a tabela que descreveu as principais diferenças entre
bytes e matriz Bt em Python Usamos bytes quando você quer trabalhar com dados que não
devem mudar. E usamos a matriz de bytes quando precisamos de uma
sequência mutável de mordidas, que pode ser atualizada ou Por enquanto, isso é tudo. Nos
vemos na próxima aula.
15. Trabalhando com loops e condições em Python: Já nos encontramos
com esse operador antes. Agora vamos dar uma
olhada mais de perto. O operador I em Python
seleciona ações a serem
executadas durante a operação do
programa,
dependendo das condições dependendo das Se o resultado da primeira verificação de
condição for verdadeiro, o primeiro bloco
de código será executado. Caso contrário, a segunda
condição será verificada
e, se retornar verdadeira
, o bloco dois será executado e assim por diante até que uma condição
que retorne verdadeira seja encontrada. Ou então a condição
é atingida. Se o else estiver ausente e todas as verificações de
condição retornarem falsas, nenhum dos
blocos ramificados será executado O bloco de código após a instrução
If é obrigatório. Se for necessário
indicar que nada deve ser
executado nesse bloco, a instrução pass será usada. é colocado onde
o comando deveria estar, mas não executa nenhuma ação. Em Python, você pode usar uma abreviação para a
declaração chamada operador condicional ternário ou expressão condicional para escrever
uma declaração
eval uma abreviação para a
declaração chamada
operador condicional ternário ou expressão condicional para escrever
uma declaração
eval em uma única linha. Essa abreviatura é
particularmente útil
para operações ou
atribuições condicionais simples Ok, vamos tentar. Imagine que queremos verificar
se um número é par ou ímpar e atribuir um resultado
com base nessa condição A expressão é usada para
verificar se um número é par. O operador de módulo retorna
o restante de uma divisão. Se o resto de uma divisão igual a zero, então obtemos verdadeiro,
então o número é par, ou se for falso, então o número é então o número Usando o operador ternário,
fica assim. Temos expressão
na condição
e, se a condição for verdadeira, temos par e ela é
atribuída ao resultado. Essas duas expressões
são absolutamente equivalentes e produzem
o mesmo resultado. Mas se a condição
for falsa, ficamos estranhos. Vamos dar uma olhada em
loop e Python. Esta é uma
declaração de fluxo de controle usada para iterar ovário, como um dicionário ou sequência de caracteres
Les Apple ou mesmo Ele executa um bloco de código para cada item na sequência É comumente usado quando você
precisa realizar uma ação um número específico de vezes e deseja processar cada
item em uma coleção. O loop de quatro e o python
pegam cada item de uma sequência um por um, e o atribuem à
variável de loop O bloco
de código recuado após a coluna é executado uma vez para cada item
na sequência Então, vamos começar com um
exemplo simples de quatro voltas. Eu criei uma lista, a
chamei de números. Em seguida, criei quatro loops, iterei os números
e imprimi cada número Então, o loop itera
sobre a lista. Para cada item na lista, o número
da variável de loop assume
seu valor e, em seguida,
imprime a instrução, imprime o valor do
número em cada iteração Podemos fazer a mesma coisa,
mas vou usar o alcance. A função Range é
frequentemente usada com quatro loops para gerar
uma sequência de números É útil quando você quer
repetir um número específico de vezes. Essa função tem três
parâmetros, start, stop e step, mas só podemos
passar um argumento. No meu exemplo, serão cinco. Portanto, o intervalo gera números de zero a cinco, mas
não incluindo cinco. A variável de loop I
assume cada valor 0 a 4 e, em seguida, a imprimiremos Você também pode especificar o
valor inicial e o valor da etapa. E neste exemplo, função range gera
números começando em dois, terminando antes de dez e
incrementando Você pode usar quatro loops para iterar sobre caracteres
em uma string, o que é útil para tarefas que exigem
manipulação ou análise de strings Nesse caso, cada caractere
da string Python é atribuído à letra da
variável de loop em
cada iteração
e, em seguida, imprimi um
por um, Como eu disse antes, os quatro loops podem iterar sobre qualquer objeto
iterável, incluindo listas, tabelas,
dicionários e conjuntos Aqui podemos ver um
exemplo com listas. O mesmo que podemos
ter com taples. O quatro loop é uma ferramenta poderosa para iterar uma sequência É comumente usado com
a função range para repetir um
número específico de vezes. Com quatro loops,
você pode iterar sobre listas, strings, tuplas
e outros iteráveis, tornando-o uma opção versátil para Também temos wild
loop e Python. Também é uma
declaração de fluxo de controle que permite que o código seja executado repetidamente
com base em uma determinada condição. O loop continua em execução
enquanto a
condição especificada for verdadeira. É particularmente útil quando o número de iterações
não é conhecido com antecedência e você deseja continuar fazendo loop até que uma determinada O loop curinga verifica a
condição antes de cada iteração. Se a condição for verdadeira, o código dentro do bloco de
loop será executado. Depois que o código é executado, a condição é verificada novamente
e, se ainda for verdadeira, o bloco de código será executado novamente. Esse processo se repete até que a condição seja
avaliada como falsa, momento em que o
loop termina e o programa passa para a
próxima seção do código Então, aqui temos condições. Essa é uma expressão lógica
que retorna verdadeiro ou falso. Quando verdadeiro, o loop continua;
quando falso, o loop é interrompido E então temos um corpo de loop, o bloco de código recuado que é executado repetidamente,
desde que a condição seja verdadeira Neste exemplo, o loop
começa com a contagem um. Em seguida, a contagem de condições menor
ou igual a cinco é verificada. Como a contagem é inicialmente uma, a condição é verdadeira
e o loop é executado, e imprimimos que a contagem é uma Em seguida, foi incrementado em um. O loop então verifica
a condição novamente e isso se repete até que a
contagem seja maior que cinco Podemos criar um loop infinito. Ela continuará indefinidamente se a condição
nunca se tornar falsa Para interromper esse loop, podemos pressionar Control
plus C ou common plus C. Depende do seu sistema
operacional e das configurações. Na próxima lição,
abordaremos as declarações de interrupção e contínuas para
controlar o fluxo de loops
16. Fluxo de controle em Python: instruções quebrar e continuar: Bem vindos de volta, pessoal. Agora vamos aprender as declarações break and
continue em Python Eles são usados
para controlar loops durante e durante. Cada declaração tem
um propósito específico. Break encerra imediatamente
o loop em que está e o programa continua com a próxima instrução
após o loop A instrução break é
usada quando você precisa
sair de um loop antes que ele termine
naturalmente Isso é útil
quando você encontra uma condição específica e não precisa mais
continuar fazendo o loop Então, imagine que temos uma
lista de números e
queremos parar de repetir
assim que encontrarmos
o número sete Para isso, eu uso quatro loops
e, por dentro, escrevo a condição. Se o número for igual a sete, trazemos a mensagem E então eu uso o operador de
pausa. Mas até cumprirmos a condição, imprimiremos os números. Se eu executar esse código, ficaremos assim. O loop itera sobre cada
número na lista de números
e, quando o número é igual a sete,
a condição if Então, as
instruções de interrupção são executadas. O loop para imediatamente, então os números oito e nove nunca
são impressos. A instrução contínua
é usada para pular a iteração atual do loop e continuar
com
a próxima Isso é útil quando determinadas
condições são atendidas e você não deseja executar o código restante do
loop para essa iteração. Então, aqui podemos ver
claramente que iniciamos o ciclo e cumprimos a condição. Se a condição for verdadeira, a
instrução contínua será executada e a função
de impressão não será executada. Não imprimiremos nada. Voltamos ao
início do loop, ignorando a função de impressão Mas se a condição não for atendida, executamos a
função de impressão dentro dos quatro loops e
somente depois disso, continuaremos o loop. Eu mudo um pouco o
código que tínhamos antes. Eu substituo o
operador break por continua, uma pequena mensagem de reescrita E execute novamente o código. E aqui podemos ver que
pulamos o número sete. A segunda função de impressão com número não imprimiu nada. Vemos na mensagem que
devemos pular os sete. E se eu remover essa impressão, porque era apenas uma
informação para nós. E agora eu executo novamente o código, vemos que a condição foi
atendida e sete não está aqui. Imprimimos os
números desde que a condição não fosse atendida
e continuávamos recebendo falsos. Assim que terminamos,
a declaração contínua foi executada e
pulamos a impressão,
mas só deixamos de imprimir o número sete O loop continuou funcionando e imprimimos os
outros números. Você pode usar declarações de interrupção e
contínuas para controlar o fluxo de um loop. Aqui, eu inicializo uma variável I e a defino como igual a zero, essa variável servirá como um contador para controlar o loop O loop while continuará sendo
executado enquanto a condição I
menor que dez for verdadeira. Nesse caso, o loop continuará funcionando até que I seja igual a dez. Eu imprimo o valor I
para cada iteração. Dentro do loop, temos a
condição de quebrar esse loop. Essa declaração I verifica se o valor de I é
igual a cinco ou Se essa condição for verdadeira, a instrução break é executada e imediatamente
encerra o loop e aqui eu incremento o
valor de I Aqui podemos ver o operador
mais igual. É um exemplo de um operador de
atribuição composto. É uma forma
abreviada de adicionar um valor a
uma variável e atribuir o resultado a essa
variável em uma única etapa Em outras palavras, na adição de
lugares. É uma maneira rápida de dizer: aumente o valor dessa variável em um
determinado valor. Também temos o operador
menos igual. Funciona de forma semelhante. Mas, em vez de adicionar, ele subtrai um valor
da variável e atribui o resultado de
volta à O loop começa em I igual a zero e incrementa
I em um Quando I é igual a cinco,
a instrução break é
executada, encerrando o loop Vou substituir a
versão abreviada pela completa e obteremos o mesmo resultado Mesmo que a condição ainda
seja I inferior a dez, o circuito para mais cedo por
causa do operador do freio Vamos passar para a declaração
contínua. Eu mudo um pouco o código. Se eu executar esse código, podemos ver claramente que
os loops continuam imprimindo cinco porque continua é
chamado quando I é igual Esse operador interrompe
a iteração atual, então a impressão I não é executada
quando I é igual Nosso loop então passa para
a próxima iteração, continuando com I igual a seis, e aqui podemos ver isso claramente Usando break e continua, podemos controlar a execução dos
loops Você pode lidar com muitos
cenários diferentes com o le loop. Mas não apenas com o while, mas
também com o loop anterior, combinação de loops for e while
com condições aninhadas fornece flexibilidade
e controle, permitindo que você itere com eficiência enquanto
aplica Tanto as declarações de interrupção quanto as
contínuas são usadas para controlar
o fluxo de loops Se você estiver usando while
ou for loop, isso importa. Eles ajudam a gerenciar a
execução dentro dos loops, mas se comportam de forma diferente
em termos de como influenciam
a operação dos loops A instrução break é usada
para sair permanentemente de um loop. A instrução contínua
é usada para pular a iteração atual
e passar para a próxima sem
encerrar todo o loop Isso faz com que o
programa passe para a próxima
iteração do loop A escolha entre interromper
e continuar depende da lógica e
dos requisitos
de
controle de fluxo de suas tarefas específicas.
17. Trabalhando com loops aninhados e declarações condicionais em Python: Bem vindos de volta, pessoal.
Vamos nos aprofundar em um conceito importante na programação de
loops e condições aninhados, por que eles são úteis e como você pode aplicá-los para resolver problemas
mais complexos Na programação, os
loops nos permitem
repetir um conjunto de ações
e condições, tomemos decisões em nosso código com base em
determinados critérios Já aprendemos isso antes
na lição anterior. Mas quando falamos sobre loops e condições
aninhados, queremos dizer que um loop ou condição é colocado
dentro Vamos começar com quatro voltas. Vou criar duas listas. O primeiro será de animais e contém três espécies. O segundo serão os habitats. Usaremos essas duas
listas para gerar combinações de cada
animal com cada habitat. Então, no primeiro loop,
iteramos cada item na
lista de animais, um por um Durante cada ciclo do ciclo de
quatro animais em animais, a variável animal
assumirá o valor de cada elemento nos
animais e na sequência. Na primeira iteração, o
animal será leão. Na segunda iteração, animal será pinguim Na terceira iteração, animal será elefante Então temos o loop interno. Esse loop está aninhado
dentro do loop externo. Para cada animal, o circuito
interno
percorrerá todos os habitats
da lista de habitats Cada vez que o loop interno é executado, a variável habitat
assume o valor de cada elemento na lista de
habitats, um por um Esse circuito interno se repete para cada animal
do circuito externo, que significa que ele passará por
todos os habitats de cada Por exemplo, quando o
animal é um leão, o circuito interno se
repete três vezes,
estabelecendo como habitat a savana, depois a Antártica e, finalmente, depois a Antártica e, finalmente A instrução de impressão é executada
sempre que o loop interno é executado. Ele imprimirá
os valores atuais de animal e habitat. Vamos ver isso
juntos como um par. Isso cria todas as combinações
possíveis de animais e habitats Então, a primeira iteração do animal do circuito externo é
o leão e, em seguida, o loop interno
com o animal como leão, temos o habitat na savana,
então ele traz a savana então ele traz Em seguida, o habitat é a Antártica, então traz a Antártica do leão Finalmente, o habitat é pastagem,
então traz pastagens para leões A segunda iteração do animal do
loop externo é o pinguim
e, em seguida, o loop interno
faz o mesmo trabalho Temos savana de pinguins, Antártica de pinguins e pinguins Com a terceira iteração,
temos animais como elefantes, e o loop interno, novamente,
faz o mesmo trabalho O resultado dessa estrutura de circuito
em mastro é uma combinação de cada
animal com cada habitat Vamos continuar com as condições
aninhadas. As condições aninhadas nos permitem verificar vários
níveis de critérios Por exemplo, aqui eu inicializei
duas variáveis A e B. Essas variáveis serão usadas para avaliar as condições
no código Em seguida, escrevo o código
com condições aninhadas. Essa é a primeira condição, e aqui verificamos se o valor
de A é maior que dez. Essa condição é verdadeira, então o código dentro desse
Eblock será executado Agora que estamos dentro do bloco
I A maior que dez, encontramos uma
segunda declaração I. O segundo I está aninhado
no primeiro, o que significa que só funciona se a primeira condição A
maior que dez for verdadeira Neste IF aninhado, verificamos se B é
maior que dois Como B é cinco, o que na verdade é
maior do que dois, essa condição também é verdadeira. Portanto, o código dentro desse bloco I
aninhado será executado. Como A maior que dez e B
maior que dois são verdadeiros, o programa alcança essa linha e imprimirá a mensagem. A é maior que dez e
B é maior que dois. Essa saída indica que
ambas as condições foram atendidas. Esta cláusula s é anexada
à condição interna se
B for maior que dois Ele fornece um resultado
alternativo se a declaração E aninhada, se B maior que
dois, fosse falsa Em outras palavras, se a
maior que dez for verdadeiro, mas B maior que dois for falso, o programa executaria
esse bloco Ls em vez disso. Como B maior que dois é
realmente verdadeiro em nosso caso, esse bloco s é
ignorado nessa execução. O bloco eLS é anexado
à primeira instrução If externa. Na verificação inicial, A
maior que dez, onde o
falso significado A era dez ou menos, o programa pularia todo o código interno
e pularia direto para esse bloco els e imprimiria A não é
maior que dez Como A é de fato
maior que dez, em nosso caso também, esse bloco els também
é ignorado nesta execução. Vamos considerar loops
silvestres aninhados. Essa estrutura de loop aninhado é útil para tarefas
que envolvem grades e tabelas nas quais
você precisa iterar em linhas e colunas Então, primeiro eu
inicializo a função da variável
e a defino como zero Essa variável representará o papel em nossa estrutura
semelhante a uma grade. Então eu escrevo um loop externo. Esse loop é executado desde que a
linha seja menor que cinco. Como a linha começa em zero, o loop continuará
até que a linha atinja cinco para cada iteração
do loop externo Passamos por um
ciclo completo do loop interno Estamos dentro do loop externo
e, antes de entrarmos
no loop interno, definimos a coluna 20. Essa redefinição garante
que, para cada neurônio, comecemos as colunas
do início Portanto, a coluna é igual a zero. Pelo que entendemos,
a variável coluna representa a
posição da coluna em nossa grade. Agora, vamos escrever
o loop i interno. Esse loop interno controla
os valores da coluna. Ele será executado desde que a
coluna seja menor que quatro, significa que cada linha terá
quatro colunas, variando de 0 a 3 Para cada linha, esse loop
interno será executado quatro vezes, saudando os valores de quatro
colunas para cada linha Dentro do loop interno, essa linha imprime os valores atuais da
linha e da coluna. Isso nos dá posições
para cada célula
na grade com o
formato, linha e coluna. Como o loop interno é executado
quatro vezes para cada linha, ele imprimirá quatro
valores de coluna para cada valor de linha. Depois de imprimir a linha e a coluna
atuais, incrementamos coluna por uma Esse incremento é crucial
para passar para a próxima coluna. Sem ele, o
loop interno se repetiria infinitamente, pois a coluna sempre
permaneceria em zero Quando a coluna atinge quatro, a condição do loop interno, coluna menor que
quatro, se torna falsa, encerrando o loop interno e retornando o controle
ao loop externo. E aqui, quando retornamos
ao loop externo, incrementamos a função em uma
para passar para a próxima linha Esse processo se repete
até que a linha atinja cinco, momento em que a linha de condição menor que cinco no loop
externo se torna falsa e o programa inteiro é interrompido A saída desse
código imprimirá todas as combinações possíveis
da linha 0-4 e das colunas 0-3, criando um grau de loops Nested wi podem ser usados
para gerenciar o estado do jogo, iterar possíveis movimentos
ou verificar as condições
em todo o tabuleiro ou verificar as condições
em todo Nos vemos na próxima aula.
18. Usando loops com estruturas de dados aninhadas em Python: Bem vindos de volta, pessoal. Hoje, trabalharemos com tipos de dados
aninhados e começaremos com uma lista aninhada Lista aninhada é uma lista que contém outras listas
como seus elementos Podemos pensar nisso
como uma lista de listas. Neste exemplo, estamos
usando a lista aninhada chamada grade que representa uma grade de
três por três Cada lista interna
representa uma função, e cada elemento individual
nessas listas é como
uma célula na grade. Aqui na grade tem três
linhas e três colunas. Nessa estrutura, a grade zero
acessa a primeira linha. grade um acessa a segunda linha e a grade dois acessa
a terceira O elemento individual do eixo dentro de uma
linha específica em uma coluna, você pode usar a indexação dupla Por exemplo, a grade zero, zero, recupera o elemento na primeira linha e na primeira
coluna, que é um, e a grade um e dois
recupera o elemento na
segunda linha e na terceira coluna, que é seis Para imprimir cada
elemento na grade, podemos usar o ninho por laço que vimos
na lição anterior. O loop externo itera
em cada linha, enquanto o loop interno itera em cada
elemento dentro dessa O comando print imprime o valor seguido por um espaço
em vez de uma nova linha. Isso é para garantir que o valor
de
cada impresso na mesma linha. Depois que o loop interno é
concluído para cada linha, impressão é chamada
sem nenhum argumento Essa quebra de linha garante que valor de
cada linha seja
impresso em uma nova linha. E aqui podemos ver o resultado. Essa saída mostra os valores em grade impressos no formato de grade de três
por três. As listas aninhadas permitem representação de
dados multidimensionais Mas também temos
outros tipos de dados. Vamos continuar com os dicionários
da NASDA. dicionário NASDA é
um dicionário que contém outros dicionários
como seus valores Essa estrutura é
útil quando você deseja armazenar dados relacionados sobre várias entidades e precisa uma forma de organizar informações
complexas. Neste exemplo, temos
um dicionário chamado usuários que cada chave representa um ID de usuário
exclusivo, como usuário um, usuário dois, e cada valor é outro dicionário contendo
detalhes sobre esse usuário. Esse dicionário, as chaves
externas do dicionário, usuário um, usuário dois, usuário três, identificam usuários
diferentes. Cada valor
associado a essas chaves é um dicionário interno que contém os detalhes do usuário, como
nome, idade e localização. Nós podemos ter acesso. Por exemplo, usuário 1 retorna o nome, Nick, e todas as informações sobre esse
usuário para acessar a idade de Bob. Por exemplo, podemos usar
usuários User two ag e ele retorna 30. Para imprimir as informações de cada
usuário, podemos usar loops aninhados
para iterar
nos dicionários externo e
interno Veja como funciona. Os itens do usuário retornam
cada par de valores-chave no dicionário do usuário. Vimos isso na lição
anterior. E nesse loop, o nome de usuário contém a
chave do dicionário externo Usuário um, usuário dois, e os detalhes contêm
o valor de cada usuário, que é o dicionário interno que
contém as informações desse
usuário O loop itera sobre
cada usuário em usuários. Portanto, o código dentro do
loop será executado três
vezes, uma para cada usuário. Para cada usuário, imprimimos o valor
do nome de usuário como um cabeçalho. O nome do usuário nos fornece chave
do dicionário Ater
que representa um ID de usuário exclusivo Então temos o loop interno. Aqui temos itens de detalhes e ele retorna os pares de
valores-chave no dicionário
interno. Para cada par de valores-chave
no dicionário interno, chave contém o
tipo de detalhe específico, nome, idade, localização, e o valor contém o valor
real do detalhe. O loop interno será
executado três vezes para cada usuário, pois cada
dicionário do usuário contém três chaves. Dentro do loop interno, imprimimos detalhes de
cada usuário de
forma formatada Tecla capitalize, usamos para capitalizar o nome do detalhe
para uma saída mais legível E depois da chave,
imprimimos o valor. Isso nos permite
imprimir o nome, a
idade e a localização do usuário em formato legível Após a conclusão do loop interno, usamos a impressão sem argumentos
para adicionar uma quebra de linha, separando
visualmente os detalhes de
cada usuário Portanto, a primeira iteração do
loop externo para o usuário um e
temos o nome de usuário usuário um Então, temos detalhes como
nome, idade e localização, e o loop interno os imprime
, loop interno os imprime seguida, a segunda
iteração do loop externo para o usuário dois, e obtemos o nome de usuário usuário dois e, em seguida, o
loop interno imprime os detalhes E o mesmo que vemos com terceira iteração de loop externo
apenas para o usuário Podemos usar NAT e dicionários para armazenamento estruturado
de dados complexos Ele facilita o acesso
e a exibição
hierárquica das informações Vamos nos aprofundar
e agora estamos combinando listas
e dicionários aninhados Podemos combinar vários
tipos de dados em uma estrutura aninhada. Por exemplo, aqui temos
uma lista de dicionários. A variável products é uma lista contendo
vários dicionários Cada dicionário representa
um único produto e contém pares de valores-chave para diferentes atributos
desse produto. Especificamente, cada
dicionário tem três chaves, nome, preço e estoque. Quais detalhes da loja
sobre o nome,
preço, quantidade e estoque dos produtos . Portanto, em produtos,
temos dois dicionários, cada um representando um
produto exclusivo com seus detalhes As quatro iterações de loop cada dicionário da lista, e aqui o produto é uma
variável que abordará cada produto em
produtos, um por um E durante cada iteração, produto se refere a
um dicionário Dentro do loop, usamos o dicionário do produto
para acessar cada atributo como nome, preço e estoque do
dicionário
do produto atual, por meio de sua chave. O nome do produto acessa o valor associado à chave do nome O mesmo que temos com o
preço do produto e o estoque do produto. E, eventualmente, aqui temos
saídas em formato legível. E vamos trabalhar com
uma lista de itens básicos. Eu inicializei a
variável itens de mercearia, e esta será
uma lista Cada tauple contém
dois elementos, o nome do item de mercearia
e o preço correspondente A estrutura externa é uma lista, que nos permite armazenar vários itens em uma coleção
ordenada. Cada item da lista é uma estrutura de dados dupla
que pode conter vários vos. As tabelas são imutáveis e
sabemos que, na lição anterior,
isso significa que, uma vez
criadas,
suas varios não podem ser alteradas suas varios não podem ser Isso é muito útil para
representar pares fixos de dados. Cada dobradinha na lista tinha
a seguinte estrutura, nome do
item e preço. E então eu escrevo os quatro loops. O loop de quatro iterações é repetido sobre cada dobro na lista de itens de
mercearia. Aqui, item e preço
são variáveis que assumirão as
variáveis de cada tupla,
primeiro e segundo elementos, primeiro e segundo elementos respectivamente, durante
cada iteração Esse processo de desembalagem significa
que, para cada iteração, item recebe o nome
do item de mercearia e o preço recebe o preço correspondente Dentro do loop, o código usa os valores descompactados para
imprimir a saída formatada. O item insere o nome
do item na string. preço insere o preço
de até duas casas decimais, garantindo que ele sempre seja
exibido como um valor monetário Quando esse loop for executado, ele produzirá a
seguinte saída para a lista fornecida de itens
de mercearia. Combinar diferentes
tipos de ninho e dados é particularmente útil em aplicações do mundo
real. Ao utilizar estruturas NSTA, podemos criar uma representação de dados complexa e
organizada que aprimora nossa capacidade de
gerenciar Por enquanto, isso é tudo. Nos
vemos na próxima aula.
19. Como entender as listas em Python: Bem-vindo de volta. um recurso poderoso em
Python que aprimora a eficiência
, a legibilidade
e a expressividade do código ,
tornando-a a
escolha preferida A
compreensão de listas é
um recurso poderoso em
Python que aprimora a eficiência
, a legibilidade
e a expressividade do código,
tornando-a a
escolha preferida de muitos desenvolvedores ao trabalhar com listas. Isso pode tornar seu código mais
limpo e mais legível. Ele permite que você expresse lógica
complexa de geração de listas
em uma única linha de código, reduzindo
significativamente a quantidade de código que você precisa escrever. Então eu inicializei um novo valor, e aqui temos quatro loops Esse loop itera ou um intervalo de números gerados pela
função range 11, que produz os
inteiros de 0 a A variável X assume o valor de cada inteiro
na sequência, um por um, e o método append
é usado para adicionar cada valor de X à Após cada iteração, um novo número será
adicionado à minha lista O loop é executado 11 vezes de acordo com os números de
zero a dez Como resultado, podemos imprimir
e ver que temos uma lista. No entanto, podemos escrever isso de uma
forma muito mais curta, rápida e legível Eu inicializei a
variável Mil list two. compreensão de listas é uma forma
concisa de criar listas
combinando um loop
e uma expressão
em uma linha. Temos X. O valor que será
incluído na nova lista Ele representa cada
número na sequência. Para cada número no intervalo, o valor X é
adicionado diretamente ao Mist two. No meu caso, como não
há
condição ou transformação adicional, a compreensão da lista
simplesmente cria uma lista dos valores gerados
pelo intervalo da função E se eu imprimir esse código, veremos dois resultados totalmente
idênticos. Podemos gerar uma
nova lista aplicando uma expressão a cada elemento
em um iterável existente Pode ser tupla,
string ou lista
e, opcionalmente, podemos filtrar elementos
com base em Essa abordagem
combina a duração
e a lógica condicional em
uma única linha legível Mas se eu
alterar um pouco esse código, posso mostrar como podemos
aplicar uma expressão a
cada valor, um por um, e
criar uma nova lista a partir do intervalo de
funções. Mas, em vez do resultado anterior, posso ver não apenas o valor
X adicionado à nova lista, mas o quadrado de X. Há uma expressão
que especifica o que cada elemento
na nova lista deve ser Nesse caso, X calcula
o quadrado de X.
O operador em Python é Então, aqui temos números quadrados. A sintaxe não é
tão complicada. Tudo o que tivermos
à esquerda será adicionado à lista a cada
iteração dos quatro loops Vamos considerar mais exemplos. Aqui é criada uma lista com nomes cidades que contém
cinco cadeias de caracteres, cada uma representando uma cidade
diferente, Nova York, Los Angeles, Chicago,
Houston e Londres Em seguida, inicializamos uma
lista vazia chamada nova lista. Essa lista acabará por
conter as
cidades de vilas que não correspondem à cidade
especificada em Nova York. E aqui eu escrevo para loop. Esse loop itera sobre cada
elemento na lista da cidade. A variável X
assume o valor de cada cidade na lista
durante cada iteração. Dentro do loop, verificamos se
X não é igual a Nova York. Se a condição for verdadeira, executaremos a próxima linha. Se a condição for atendida, usamos o método Band para
adicionar X à nova lista. Isso cria uma nova lista ao incluir todas as cidades,
exceto Nova York Se eu executar esse código,
ficarei assim. Aqui temos uma nova
lista onde podemos ver todas as cidades, exceto Nova York. Mas vamos reescrevê-lo. Esse operador é um operador
de comparação. Na programação, isso
significa “não é igual a dois”. É usado para comparar
dois valores ou expressões para determinar se eles são diferentes um
do outro. Se os valores que estão sendo
comparados não forem os mesmos. O operador retorna o valor verdadeiro. Em outros casos, ele retorna falso. Então, vamos escrever nossa primeira compreensão da
lista. Essa linha faz a mesma
coisa nos quatro loops, mas de uma forma mais concisa
e pitônica, a estrutura geral da compreensão
da lista E aqui X é a expressão. Para X em cidades, ele lê a lista de cidades da
mesma forma que o loop de quatro. Então, temos uma linha
que filtra
todas as cidades que estão em
Nova York. Essa linha cria uma nova lista
diretamente usando as toneladas que atendem às condições especificadas
na compreensão da lista Então, se eu imprimir esse código, podemos ver o resultado. Vamos tornar a tarefa um
pouco mais desafiadora. Aqui eu escrevo é compreensão
com condição. X é o valor que
será incluído
na nova lista, como eu disse antes, então temos quatro loops que fazem a mesma
coisa que antes. Mas então temos condições. Esse é um filtro
que inclui apenas números em que a expressão é
avaliada como verdadeira Nesse caso, ele verifica se X é uniforme usando
o operador do módulo. Ele verifica se o resto que X é dividido
por dois é zero A compreensão da lista
é lida por meio cada número gerado
pelo intervalo de funções, que são zero, um, dois, três e até dez Se X for par, ele será incluído
nos novos eventos da lista. Se X for ímpar, será excluído. Como resultado, temos assim. Posso reescrevê-lo como um loop for
tradicional,
mas, neste caso,
incluímos a instrução If E somente após essa condição, se for verdadeira, abandonamos o valor
e para uma nova lista. Então, se eu executar esse código, veremos resultados totalmente
idênticos. Aqui eu crio uma lista chamada palavras contendo três cadeias de caracteres. Olá, mundo e Python. Vamos imaginar que eu queira saber o tamanho de cada
palavra nesta lista. Quero ter a
saída final como uma lista de números inteiros representando o número de caracteres em cada palavra
correspondente E para isso, posso usar
a compreensão da lista. À esquerda,
temos a função A que calcula o comprimento
de cada string na lista Essa função retorna o número de caracteres na string. Então, temos a
iteração palavra em palavras. Essa parte itera sobre cada
elemento na lista de palavras. A palavra variável
assume o valor de cada string na lista
durante a iteração. Portanto, a compreensão é interrompida na
lista de palavras. Para cada palavra, ele calcula o comprimento
usando uma função O comprimento resultante é coletado em uma nova
lista chamada comprimento. E temos para hello, o comprimento é cinco, para world, o comprimento é cinco, e para Python,
o comprimento é Vamos usar um exemplo avançado. Quero considerar um exemplo de
uma compreensão avançada de listas que usa várias condições
em uma única linha Eu inicializei números de
listas vazias. Então eu tenho quatro loops que
iteram sobre os números de 0 a 50, e dentro de quatro loops, eu tenho várias declarações O primeiro verificará
se X é divisível por dois. No segundo, verificaremos se
o X é divisível por três e o terceiro verificaremos se
o X é divisível por cinco Se X atender a todas as condições, ele será adicionado à lista de números. A saída seria assim. Como podemos
escrevê-lo de forma mais curta? Da esquerda, temos uma entidade que
adicionaremos à lista. Então, temos quatro loops em que
geramos o número 0-50
e, em seguida, temos
as condições uma por uma Vou torná-lo mais
legível assim. No final, imprimo números
e temos o mesmo resultado. Vamos considerar outro
exemplo em que
teremos dois loops
incluídos em quatro Eu defino a grade variável e aqui eu salvo a lista
bidimensional. Então eu inicializo minha lista. É só uma lista vazia. Isso manterá o resultado
achatado da grade. Eventualmente, meu objetivo é criar a partir de uma lista bidimensional
apenas uma lista dimensional. Nos primeiros quatro ciclos, eu repito sobre cada sublista. Então, na primeira iteração, terei a primeira
linha um, dois, três Na segunda iteração,
terei a linha quatro, cinco, seis e
na terceira iteração,
sete, oito, nove.
No loop interno, eu itero sobre cada elemento
na Então, aqui, minha coluna variável assume o valor do elemento
atual na linha. Para a primeira linha, minha variável será uma, depois
duas e depois três. Para a segunda linha
, serão quatro, depois cinco, depois seis, e para a terceira
, serão sete, oito, nove. E então eu uso o método
append que adiciona cada elemento da linha
à minha lista, um por um Ao final dos loops aninhados, minha lista conterá
todos os elementos da grade em uma única lista achatada Agora é hora de escrevê-lo
como uma compreensão de lista. Eu inicializei, novamente, minha lista. Como sempre, à esquerda, especifico que será adicionado à minha nova lista a cada iteração. Em seguida, seguindo a lógica
da execução do código, eu especifico os dois loops
conforme descrito acima Eu apenas copio. E aqui estamos, temos o mesmo resultado. Ambos os métodos fornecem a
mesma saída final, mas a menor compreensão geralmente
é preferida por sua concisão e legibilidade ao lidar com transformações simples O último, mas não menos importante, exemplo
de compreensão de listas com bloco
ELs que
categoriza uma lista de números com base no fato de eles serem divisíveis
por três Eu inicializei números variáveis. Em seguida, criei uma
lista vazia para armazenar os resultados. A primeira linha, é para loop. Ele itera sobre cada
número na lista de números
e, em seguida, eu tenho a condição If Ls Se X for divisível por três, a string divisível por três será
adicionada à variável categorizada Caso contrário, adicionaremos a
string não divisível por três. E no final, imprimimos
o resultado para cada número. Na última, obtivemos o
valor correspondente indicando se o número é
divisível por três ou não Agora, vamos escrever isso com
a menor compreensão. Pode parecer um pouco confuso, mas não é difícil Olha, temos da esquerda a entidade que vamos adicionar
à nova lista, mas não é apenas uma entidade. Vamos meio que filtrá-lo. E aqui usamos a condição
EFLSBlock. Essa
expressão condicional verifica se cada número X em números
é divisível por três Então, temos um loop que itera sobre cada
elemento em números Temos
partes de expressão esquerda e direita. À direita, temos um loop
e, a cada iteração, verificamos o valor de X. No lado esquerdo,
temos o Depende de X ser divisível
por três ou não. Divisível por três ou não divisível por três
será adicionado à nova lista Eventualmente, temos uma nova lista
em que acabamos de substituir cada valor, dependendo de ser
divisível por três ou não Com este exemplo, eu só
queria demonstrar como a declaração AFL funciona
na compreensão de listas Nos vemos na próxima aula.
20. Usando a função input() em Python: Bem vindos de volta, pessoal. Como podemos receber informações
de um usuário? Na programação,
há uma função de entrada. Ele permite que o usuário
forneça dados que o programa pode usar
para realizar cálculos. Por exemplo, um programa
pode pedir o nome do usuário e cumprimentá-lo pessoalmente
com base nessa entrada O objetivo da entrada é
tornar os aplicativos interativos. A entrada é usada para ler o valor, insira-o no teclado. Por exemplo, eu escrevo
a função de entrada
e, por dentro, uso o prompt. Isso pode ser opcional. É uma sequência de caracteres exibida
ao usuário para
orientá-lo sobre o que inserir. No meu caso, será o nome. Agora, se eu executar esse código, meu pequeno programa
pedirá que eu digite meu nome. Eu insiro meu nome, pressiono enter
e, por enquanto, meu programa
terminou de funcionar. Vou atribuir essa
linha de código a uma variável e vou chamá-la de nome e
depois vou imprimi-la. Aqui eu uso a concatenação. Você já sabe o que é. Agora eu executo esse programa novamente. Novamente, coloquei meu nome, apresentador, e aqui
estamos, recebemos uma saudação A entrada recebida
do usuário é sempre
tratada como uma string. É por isso que usamos aqui a
concatenação e ela funciona. Portanto, se a
entrada numérica for necessária, precisamos de alguma preparação Precisamos de conversão de tipo. Vamos considerar esse exemplo. A primeira linha de código
é um título ou rótulo para indicar ao usuário que o programa executará
uma operação de adição. Em seguida, a segunda e
a terceira linhas de código solicitarão
que o usuário insira dois valores. Então eu imprimo o resultado. Esse resultado eu atribuí
à nova variável. Se eu executar esse código, você verá algo estranho. Lembro que duas
entradas são tratadas como uma string. Então, aqui não tínhamos adicionado uma concatenação
incorreta. Aqui, precisamos
converter a entrada de string em número inteiro
usando a função Mas se eu executar esse código, receberei um erro novamente
porque aqui na função de impressão, concatenamos dois tipos
diferentes de dados, string Se eu converter o resultado novamente na string, trabalharei novamente. Mas podemos omitir essa etapa. Podemos usar não concatenação mas vírgulas para produzir Ele separa os valores por vírgulas
na função de impressão. E quando usamos vírgulas
na função de impressão, ele converte automaticamente cada item em uma string conforme necessário, então não há necessidade de
usar a função string Isso geralmente é mais conveniente, especialmente ao combinar
diferentes tipos de dados. Como eu disse antes, o Python lê entrada
do usuário como uma
string por padrão, mas podemos converter
essa entrada em vários tipos de dados,
dependendo do que precisamos Acabamos de considerar a conversão de
números inteiros, mas também podemos usar outros
tipos de dados Por exemplo, vamos considerar a conversão
booleana. Geralmente é usado quando
você deseja interpretar a entrada
do usuário como um valor
verdadeiro ou falso. Normalmente, nos casos em que a
entrada é sim ou não, uma pergunta. Então, aqui, uma
pergunta é feita ao usuário, eu inicializo uma variável para
armazenar a resposta do usuário Como aviso, eu uso uma pergunta
simples,
você quer continuar? Normalmente, a resposta
é sim ou não, mas pode ser um
tipo diferente de sim ou não. Então, vou criar a
segunda variável e aqui estará a conversão. Aqui eu uso a função inferior. Essa parte do código
é usada para garantir que os usuários insiram
em letras minúsculas. Isso é importante
porque a entrada do usuário pode variar em letras maiúsculas
e, ao convertê-las
em minúsculas, podemos tratar todas as
variações Depois de converter a
resposta em minúsculas, a expressão verifica se a entrada em minúsculas está na
lista de valores verdadeiros aceitos Você pode expandir essa lista
com suas próprias opções. Se a entrada em minúsculas
corresponder a um desses valores, a expressão retornará verdadeira Caso contrário, ele retornará false. Essa lógica é uma maneira rápida de
lidar com várias formas ou respostas
positivas
sem precisar de várias declarações if para
cada variação possível A variável booleana
é contínua, agora contém
verdadeiro ou falso, com base na resposta do usuário Quando a função de impressão é chamada, Python
converte automaticamente o valor booleano
armazenado no Ictinua em representação Se eu executar esse código
e inserir um, ficarei verdadeiro se eu inserir, Sim. Eu também vou me tornar realidade. E, eventualmente, se eu inserir
não, ficarei falso. Como exemplo,
também quero
mostrar como converter em flutuador Se você quiser lidar com valores
decimais, como
preços ou medidas, isso o ajudará a saber como
converter em número de
ponto flutuante Aqui, o programa
solicita que o usuário insira o preço um e o preço dois, e então eu calculo o preço
final e imprimo. A entrada que é
capturada como uma string, depois convertida em número de ponto
flutuante usando a função float, e aqui eu a uso
por dois preços Isso me permite realizar cálculos
numéricos
com o valor que obterei Então, vamos executar esse código. Eu inseri dois valores
com parte decimal. Centro de imprensa, e
eu tenho o resultado. Eventualmente, como resultado, realizamos uma operação
matemática para calcular o custo total de dois produtos, primeiro
convertendo as entradas do usuário em números de ponto flutuante Nas próximas lições,
veremos como elas podem ser usadas em estruturas de código mais
complexas. E, por enquanto, isso é tudo. Obrigada.
Nos vemos na próxima aula.
21. Introdução a funções: como criar funções em Python: Bem vindos de volta, pessoal.
Estamos iniciando uma nova seção na qual
trabalharemos com funções. Na programação, as funções são blocos de construção fundamentais. É um trecho de código reutilizável que executa uma tarefa específica Vamos começar com um exemplo simples. Já estamos familiarizados
com a declaração impressa. Vamos imaginar que eu ganhei
um grid três vezes. Se eu executar o código,
veremos três mensagens de saudação. Vamos reescrever um pouco. A função em Python
é definida usando palavra-chave DEF seguida
pelo nome
da função Aqui está a sintaxe básica. Então eu escrevo o
corpo de uma função. É o bloco de
código que contém as instruções
que a função executará quando for chamada. É definido pelo nível de
indentação após a declaração da
função O código dentro da
função deve ser
indentado corretamente para indicar que ele pertence à função
específica Se o corpo da função não
estiver recuado corretamente, Baten gerará um erro de
indentação Nesse caso, o corpo
da função será
apenas uma declaração impressa. Eu defino uma função chamada grid que, quando chamada imprimirá uma mensagem
no console. Se eu executar o código agora, não
veremos nada. Para executar o código
dentro da função, você precisa chamá-la usando seu nome
seguido de parênteses Se eu agora executar esse código, veremos a saudação E essa função imprimirá a saudação quantas
vezes eu a chamo Isso me evita de ter que copiar a saudação repetidamente Em Python, os parênteses são essenciais Eles indicam que você está
invocando a função
e, sem eles, a
função não será executada Se você indicar o parêntese, o
Python entenderá que você está
solicitando que solicitando Se você tentar chamar uma função sem
parênteses como esse,
isso não chamará Por exemplo, aqui eu
chamei a função apenas duas vezes e a terceira
não foi executada. A função também pode
aceitar argumentos. Argumentos são valores que você pode passar para uma função
ao chamá-la. Isso permite que você forneça dados
de entrada que a
função possa usar. Por exemplo, na minha função de
saudação, posso adicionar um nome de parâmetro e depois usá-lo
dentro da função Se eu executar esse código, agora mesmo, receberei um erro. Quando uma função em Python é definida com
parâmetros, no meu caso, esse parâmetro é nome, isso
significa que a função espera que determinados valores sejam
fornecidos quando é chamada Se eu tentar chamar
uma função que tenha parâmetros, mas não
forneça os argumentos necessários, Python gerará um erro
e veremos isso claramente Então eu passo o argumento Helga
e Valla, tudo funciona. Agora temos flexibilidade. A função produz saídas
diferentes com base no
argumento que fornecemos Cada vez que eu chamo a função, eu posso passar um nome diferente. A função usará esse
nome em sua operação, permitindo gerar uma saudação
personalizada Eu posso especificar
vários parâmetros. Isso significa que a função pode aceitar mais de um
argumento quando é chamada. No meu caso, eu adiciono um número e depois
o uso dentro da função. No entanto, ao chamar
a função, é fundamental fornecer todos
os argumentos necessários. Se eu chamar a função atual,
receberei um erro. Porque eu forneci apenas o nome do primeiro parâmetro e omiti o número do
segundo parâmetro Então eu adiciono, e se eu executar esse código
agora, tudo funciona. Neste momento,
consideramos apenas imprimir
dentro da função. Mas vamos considerar
a declaração de devolução. A instrução return em Python é usada dentro de uma função para sair da função e enviar o valor de volta para
o local
onde a função foi chamada Ele efetivamente encerra
a execução da função e pode passar os dados de
volta para a cor Bem, vamos começar
com um exemplo simples. Eu escrevo a função
que soma dois números. A função de adição é definida
para receber dois parâmetros, A e B, e
retornar sua soma. Quando você chama a função
com cinco e três, ela executa a adição e retorna o resultado
que é oito. No entanto, é importante
observar que simplesmente chamar a função
não exibe nada
no console. Isso ocorre porque o valor de retorno da
função não
é impresso automaticamente. O valor de retorno é gerado,
mas, a menos que você o
capture ou imprima,
ele permanece invisível
para o usuário. Para realmente ver o
resultado no console, você precisa atribuir
o valor de retorno a uma variável e depois imprimi-la. Nesse caso, veremos
o resultado no console. Vamos dar uma olhada em um exemplo mais
avançado. Quero criar uma função
que receba um nome como entrada e o retorne com a
primeira letra maiúscula Eu o chamo de nome em maiúscula e ele usa um nome de parâmetro Dentro da função, o método
capitalizado é usado para colocar a primeira letra em maiúscula
e o restante em minúscula Aprendemos esse método quando trabalhamos com o tipo de dados de
string. Em seguida, a função retorna
o nome em maiúsculas. Então eu chamo a função e capturo o
valor de retorno para o resultado. Eu intencionalmente passei
o nome em minúsculas. E, eventualmente, eu o imprimo. A função funciona
com qualquer nome, garantindo que somente a primeira
letra seja maiúscula, facilitando a
formatação adequada dos nomes Uma das principais
coisas a entender que podemos usar a função
dentro de outra função. Isso é chamado de
composição de funções usando uma função dentro da outra para criar um comportamento mais complexo. Suponha que desejemos criar uma função de
saudação que use
nossa função de nome em maiúsculas para garantir que o nome seja formatado
corretamente Portanto, a função de usuário grit usa a função de nome em
maiúsculas para garantir que o nome seja capitalizado antes de
criar a saudação Depois de colocar o nome em maiúscula, função de usuário do
Grit cria uma mensagem de saudação com
o Então, inicializei o nome formatado da
variável
e o atribuí ao resultado retornado pelo nome em
maiúsculas da função Isso é possível graças
à instrução de retorno, que fornece o resultado
do trabalho das funções. Lembro que esse
resultado é um nome em maiúscula. Em seguida, usei esse
nome em maiúsculas na mensagem de saudação
e, no final, retornei a mensagem de
saudação Então eu posso chamar a função principal. No meu caso, essa função de usuário do
grit. Eu inicializo a mensagem
variável e chamo a função grit user. Ele chama a função de
nome em maiúsculas primeiro para obter o nome em maiúsculas e, em
seguida, criar a saudação Ao compor funções dessa
forma, você pode manter seu código
organizado e reutilizável Cada função executa
uma tarefa específica e você pode combiná-las para criar
funcionalidades mais complexas. Se eu executar esse código,
receberei uma mensagem formatada. Funções em Python são objetos de
primeira classe. Eles podem ser atribuídos
a variáveis, armazenados em estruturas de dados, passados como argumentos
para outras funções e até mesmo retornados como valores
de outras funções. Eles podem aceitar um número
arbitrário de argumentos ou não
aceitar nenhum função permite que você use o código encapsulado
nelas quantas vezes for necessário durante a execução
de um programa Se eu comentar o nome em maiúsculas da
função, receberei um erro
ao tentar chamar o nome
em maiúsculas na função de usuário grit. Isso ocorre porque a função de usuário do
grit
depende da função de
nome em maiúscula, mas com o
comentário da função, nome em
maiúscula
não existe mais causando um erro quando o
usuário do grit tenta A declaração anterior em Python é um espaço reservado que não faz
nada quando é É frequentemente usado para funcionar
como um corpo temporário. Quando você precisa
definir uma função, mas ainda não escreveu
nenhum código para ela,
isso permite que o código seja
executado sem erros. Mesmo que a função
esteja vazia no momento, a instrução past permite que
você defina funções ou estruturas de
controle que ainda não fazem nada sem
causar erros. É útil para manter o
código organizado e
livre de erros enquanto você cria ou planeja partes do seu programa. Como a função de
nome em maiúsculas atualmente não faz nada, ela contém apenas
a declaração anterior Não há nenhum valor
sendo retornado. Quando uma função não retorna
explicitamente um valor, o Bydn
retorna automaticamente none por padrão Quando chamamos grit user, a mensagem da grade não recebeu nenhuma, e aqui no console, em vez do
nome, não vemos nenhuma Na próxima lição,
discutiremos os diferentes tipos
de argumentos e funções e como
trabalhar com eles. Por enquanto, isso é tudo. Nos
vemos na próxima aula.
22. Argumentos posicionais e de palavra-chave em funções Python explicadas: Bem vindos de volta, pessoal.
Agora, discutiremos quais
argumentos posicionais e de palavra-chave estão em uma função Vamos começar com argumentos
posicionais. Então, vamos imaginar
que você tem uma função e deseja passar dados
para ela para processamento. No entanto, como a função saberá exatamente quais
dados você está passando? É aqui que os argumentos
posicionais da função entram em Vamos imaginar que você está escrevendo um programa para adicionar dois números. Essa função deve pegar dois números e calcular a soma Então eu escrevo a função, depois inicializo a variável
e chamo a função O valor da primeira passagem se torna o primeiro número para o cálculo da
soma e o valor da segunda passagem
se torna o segundo. Se eu imprimir o resultado, veremos a soma
desses dois valores. Portanto, os argumentos posicionais
são passados
na mesma ordem que são especificados na chamada
da função Ao chamar a função, os valores são passados sem
especificar o nome do parâmetro Qual é o nome do parâmetro, e aqui vamos para os
principais argumentos do ort. Os argumentos Keyort são fornecidos como pares de
valores-chave em que cada
argumento tem seu próprio nome Isso permite que você passe
argumentos em qualquer ordem, mesmo que tenham sido definidos em uma ordem diferente
na própria função. Isso significa que especificamos não apenas os valores
dos argumentos, mas também seus nomes. Ao chamar a função, essa abordagem nos permite
passar argumentos em qualquer ordem e
comunicar claramente o propósito
de cada argumento. Agora vamos considerar um exemplo. Suponha que tenhamos uma
função que calcula os custos de
envio com base no
peso e na distância Podemos usar argumentos de palavras-chave para passar esses valores
para a função. Então eu escrevo a função em si. Vou chamá-lo de calcular o custo de
envio e passar o peso
e a distância como argumentos. Primeiro, definiremos as taxas, uma de 4 kg e
outra de 4 quilômetros Em seguida, usando uma fórmula simples, calcularemos
o custo
de envio multiplicando o
peso pela taxa
por quilograma e adicionando a distância multiplicada pela taxa por Por fim, retornaremos
o resultado calculado. Agora, vamos chamar a função e adicionar os
argumentos da palavra-chave
para peso e distância Também imprimiremos o
resultado que recebemos. Se eu executar esse código, obteremos o custo de entrega do
resultado. Portanto, neste exemplo, passamos os valores peso e
distância para a função, que chamamos de
calcular o custo de corte
como argumentos de palavra-chave Isso nos permite ver claramente qual valor é usado para
quê quando lemos o código. Se eu remover aqui
o nome das palavras-chave, na verdade, vou misturar a posição
nos argumentos das palavras-chave. Eu posso pausar o peso
apenas como um número e passar a distância como um argumento de
palavra-chave Nesse caso, dez será passado como um peso de
argumento posicional e 100 será passado como uma distância de argumento de
palavra-chave E isso é chamado de combinação de argumentos posicionais e de
palavras-chave Podemos usar argumentos posicionais
e de palavras-chave ao chamar uma função No entanto, os
argumentos posicionais devem vir em primeiro lugar. Eles sempre devem estar
antes dos argumentos de palavras-chave. Você não pode especificar primeiro o argumento da
palavra-chave. Por exemplo, se eu
escrever tarde igual a dez e depois especificar a
distância e colocar 100, isso seria um erro
porque, nesse caso, o primeiro argumento
é o argumento da palavra-chave e o segundo posicional, e sabemos que
não podemos Vou voltar tudo
ao que era. Os argumentos de palavras-chave tornam nosso código mais flexível e
compreensível, especialmente ao lidar com funções
mais complexas, nas quais nem sempre é
possível lembrar
a ordem de todos os parâmetros No exemplo
acima, discutimos argumentos
posicionais em que
devemos lembrar sua ordem Ao usar argumentos posicionais, o valor que passamos deve
corresponder aos parâmetros declarados na função e
não podemos confundir a
ordem dos Com argumentos de palavras-chave, no entanto, temos mais flexibilidade. Por exemplo, podemos
especificar a distância, primeiro, ao passá-la como um
parâmetro de palavra-chave e depois fornecer o peso, independentemente da ordem em que os
especificamos, nossos dados serão atribuídos
aos parâmetros correspondentes
com base em seus nomes. Vou dar outro exemplo
para deixar isso claro. Vou criar uma função grit, onde passaremos o nome e a mensagem
dos parâmetros E aqui
retornaremos uma saudação. Na primeira vez, preencherei
os parâmetros como posicionais. Eles precisam ser
passados na ordem em que são
definidos na função. Vou remover o extra
e imprimir o resultado. Como resultado, temos saudação
, nome e
mensagem no final Trocamos nossos parâmetros, obteremos um resultado inválido E nesse caso, acabamos receber uma mensagem não muito válida. Mas se isso se
aplicar a alguma fórmula, podemos obter um resultado completamente
inesperado. De acordo com o algoritmo, deveríamos cumprimentar uma pessoa específica pelo nome primeiro
e, em seguida, o parâmetro da mensagem
deveria ter sido seguido O que realmente fizemos foi
cumprimentar com a mensagem. Bem, isso
se encaixa um pouco no significado, mas imagine se a
mensagem fosse completamente diferente e depois anote o nome da
pessoa no final Não muito, mas se eu passar esses
parâmetros como palavras-chave, ou
seja, especificar nome
e mensagem especificamente
, independentemente
do fato de eles não
estarem na
mesma ordem em que foram passados para a função, obteremos um resultado válido. Vou remover a instrução de
impressão
da função anterior
para que ela não interfira. Aqui eu adicionei um parâmetro
padrão. Os parâmetros de palavra-chave podem ser opcionais se
tiverem valores padrão. Se eu já especifiquei
a mensagem em nossa função e
excluí esse parâmetro
da chamada de função, ainda
obteremos
um resultado válido. Mas com esse parâmetro hello
que eu especifiquei antes, esse será o valor padrão. Se não especificarmos
a mensagem, ela será usada em
qualquer chamada funcional. Vamos examinar rapidamente
os principais conceitos e diferenças entre argumentos posicionais
e de palavras-chave Os parâmetros posicionais são
passados para a função
na ordem em que
aparecem na definição da
função Se você passar esses parâmetros
na ordem inversa, isso afetará o resultado. Eles também são obrigatórios, o que significa que devem ser fornecidos na ordem em que
são definidos na função e sempre antes qualquer argumento de palavra-chave, se
os dois tipos estiverem presentes. Por outro lado, os parâmetros da
palavra-chave são passados para a função
como pares de valores-chave. Cada argumento tem seu próprio nome. Os parâmetros de palavra-chave não
precisam ser passados em uma ordem
específica. Eles podem ser fornecidos
em qualquer sequência. Eles também podem ser opcionais
se tiverem valor padrão. Isso significa que, se especificarmos parâmetro de
palavra-chave
com um valor padrão na definição da função, poderemos emiti-lo completamente
ao chamar a Já os argumentos posicionais,
se definidos, devem ser passados para a função
na ordem exata especificada
na definição da função Como você pode ver, entender a diferença
entre palavras-chave e parâmetros
posicionais é crucial para o uso efetivo das funções do
Python E, por enquanto, isso é tudo. Nos vemos na próxima aula.
23. Usando o empacotamento e desempacotamento de argumentos em funções Python: Bem-vindos, Ben, pessoal. Peço desculpas
pelo transtorno Eu mudei do sd para
o Pycharm. Eu tive que mudar meu espaço de trabalho. Essa foi uma medida necessária. Espero que isso não cause
muita interrupção. Agora vou
discutir sobre como empacotar e descompactar os
argumentos em uma função No pacote, o processo
consiste em reunir vários argumentos em uma
única aba ou em um dicionário Descompactar o processo de
distribuição ou extração desses argumentos de uma tabela ou dicionário ao
passá-los para uma função
ou ao chamar uma função com uma lista ou Quando você usa arcos Asterix
na definição da função, isso permite que a função
aceite um número variável de argumentos
posicionais que
são então inseridos argumentos
posicionais que
são então Você pode passar um número variável de argumentos para uma função
na forma de lista,
tupla ou conjunto, e
todos eles serão
convertidos em um grampo por meio do operador de arcos
Asterix Da mesma forma, o quarks permite descompactar
argumentos de palavras-chave de um dicionário Os pares de valores-chave
no dicionário são descompactados e passados como
argumentos de palavra-chave para a função Então, vamos praticar. Eu inicializei a
variável minha lista. Contendo quatro elementos
um, dois, três, quatro, lembro que as listas são coleções
ordenadas em Python, o que
significa que os itens têm uma ordem definida e podem ser
acessados por seu índice A segunda linha de código
executa a descompactação. Ele atribui os valores da
minha lista às variáveis A,
B, C e D. Veja como ocorre
a descompactação A obtém o valor um, o primeiro elemento da minha lista, B obtém o valor dois,
o segundo elemento, C obtém o valor três e
D obtém o valor quatro. O número de variáveis
no lado esquerdo da atribuição ABCD deve corresponder ao número
de elementos na lista Se eles não corresponderem, Python gera um Agora vamos imprimir o resultado. Eu executo o código e aqui estamos. Obtivemos o resultado
na mesma ordem em que
listamos a variável
na função de impressão. Se eu imprimir A, obteremos um. Se eu imprimir D, obteremos quatro. Deixe-me mostrar
o que vai acontecer. Se houver menos
variáveis à esquerda
, haverá
objetos na lista. Recebemos um erro,
muitos valores para descompactar. Caso não saibamos
quantos elementos seguirão após a descompactação, mas precisemos apenas dos dois
primeiros elementos, podemos usar o operador asterix Dessa forma, os dois primeiros elementos serão descompactados
nas duas primeiras variáveis e os elementos restantes serão atribuídos
como uma lista à variável C. Vamos
imprimi-la e veremos o resultado O mesmo se aplica se eu
quiser obter apenas o primeiro valor, vou manter a variável A
para esse primeiro elemento, e os elementos restantes serão colocados na variável C. Vamos considerar um
exemplo com tupla Funciona exatamente da mesma forma. Aqui eu defini a tupla. Ele contém três elementos. Lembro que as tuplas são coleções
ordenadas em
Python e são imutáveis , o que significa que seus elementos não podem ser alterados
após serem criados E aqui estou descompactando os
elementos em três variáveis. Vamos trazer o resultado,
e aqui estamos. Examinaremos
o caso em
que queremos obter o primeiro
valor durante o empacotamento, deixando os elementos restantes
em uma variável como uma lista. Mas e se quisermos obter
a última variável
durante a descompactação O separador de asterisco
colocado na frente de A coleta todos os elementos,
exceto o último, enquanto o
último elemento é atribuído a B. capturará os elementos
dois e três em
uma B capturará o último
elemento, que é quatro. Agora vamos ver como
isso funciona em funções. Aqui eu defini a função. O parâmetro arcs na definição da
função permite que funk aceite qualquer número
de argumentos posicionais O asterisco antes dos arcos todos os argumentos posicionais extras
em Isso significa que quando o funk é chamado com
vários argumentos, eles são coletados em arcos como
uma base. Então eu tenho loop. Esse loop itera sobre
cada elemento em arcos, e eu represento cada argumento
passado pelo funk, um por um Aqui estou chamando a função. Passei quatro argumentos, mas podem ser
quantos você quiser e também pode ser qualquer tipo de dados Se eu executar o código,
obteremos todos os argumentos. Graças a essa construção, posso passar qualquer número
de argumentos posicionais para a função sem
causar erros Vamos considerar outro exemplo. Então eu escrevo a função. O parâmetro quarks na definição da
função permite que a função aceite um número
variável de argumentos de
palavras-chave Asteris duplos antes
dos quarks significa que qualquer
argumento adicional de palavra-chave passado para
a função será compactado em um dicionário chamado Esses quarks conterão
os nomes e valores
dos argumentos passados, onde
as chaves são nomes de argumentos e os valores são os valores de argumentos
correspondentes Já sabemos que o método
items em um dicionário retorna
pares de chaves e valores, que permite que o loop acesse cada argumento de palavra-chave e seu
valor e quarks correspondentes Dentro do loop, imprimo cada chave e seu
valor associado em uma nova linha. Então eu chamo a função e
passo os argumentos da palavra-chave. Quando o funk é chamado, os quarks se tornam um dicionário E então, for loop itera sobre itens de quarks e imprime
cada par de valores-chave Essa técnica é
útil para criar funções
flexíveis que podem lidar com diferentes conjuntos
de argumentos nomeados. Você pode usá-lo
nessa situação
em está criando
funções que funcionam com dados dinâmicos
ou coletando dados sem saber com antecedência
qual campo será passado. Vamos considerar outro exemplo
com a descompactação do dicionário. Aqui eu defini um dicionário. Essa linha cria
um dicionário chamado data com três pares de valores-chave,
nome, idade e cidade. O dicionário contém
dados que
posteriormente serão passados como
argumentos para uma função. Então eu defino a função e essa função
precisará de três parâmetros,
nome, idade e cidade. Dentro da função,
imprimirei os valores desses parâmetros
em uma string formatada Vamos descompactar o dicionário
e chamar a função. Ao chamar funk, a sintaxe de
dados double asterix Ele descompacta o dicionário para
que cada par de valores-chave nos dados seja passado como argumentos
de palavra-chave separados para funcionar Essencialmente, os dados do double asterix traduzem o dicionário em argumentos de
palavras-chave individuais , como se você tivesse escrito Veja o que acontece
durante a descompactação. O nome da chave do
dicionário corresponde ao parâmetro
name O nome obtém o valor próprio. A chave H é combinada
com o parâmetro H, então H obtém o valor 23 E a cidade-chave é combinada
com o parâmetro city, então City obtém o valor LA Você pode usá-lo se tiver
uma função que exija vários argumentos
e quiser
preenchê-los a partir de um dicionário
com teclas correspondentes. Essa técnica é chamada empacotamento de
dicionários e torna seu código flexível e
mais fácil de manter, especialmente em aplicativos
complexos em que os dados geralmente vêm
como Por enquanto, isso é tudo. Nos
vemos na próxima aula.
24. Como entender as funções Lambda em Python: Bem vindos de volta, pessoal. Vamos dar uma olhada nas funções do Lambda em Python As funções Lambda em
Python são um recurso poderoso que permite a criação pequenas funções
anônimas em tempo
de Ele fornece uma maneira de
escrever funções curtas e
descartáveis
sem a necessidade uma definição formal de função
usando a palavra-chave DEF palavra-chave Lambda indica que você está definindo uma função
Lambda Então temos os argumentos. Esses são os
parâmetros de entrada para a função. Você pode ter vários
argumentos separados
por vírgulas e expressões Essa é uma expressão única que a função Lambda
avalia e retorna Diferentemente das funções regulares,
as funções amda só podem conter uma única expressão e não podem incluir várias
declarações ou anotações Eles não têm nome e
isso os torna anônimos. Isso é útil para funções
curtas que não são usadas em outros lugares. Vamos considerar o
primeiro exemplo. Neste exemplo, é uma função Lambda que
recebe dois argumentos, X e Y, e retorna sua soma A função Lambda é
chamada com três e cinco, resultando em oito.
Se eu executar esse código, obteremos o resultado Se eu reescrever essa função como função
normal, ela
pode ficar assim Aqui temos duas funções
idênticas. Vamos considerar a
função Lambda sem argumentos. Você também pode criar
uma função Lambda que não aceita argumentos A função Islamda
retorna uma mensagem de saudação e pode ser chamada
sem nenhum parâmetro Quero observar que toda
a função é atribuída à grade de
variáveis. Essa linha basicamente diz: armazene a função Islamda
na grade de variáveis Neste ponto, a grade
não contém um valor padrão, como
uma string ou número. Em vez disso, ele contém uma referência
à função Lambda. Como a grade contém
uma função Lambda, ela é considerada chamável Em Python, qualquer variável
que possa ser chamada função usando parênteses Quando coloco
parênteses após a grade, o
Python trata isso como uma chamada de função e
tenta chamar qualquer grade a Não podemos fazer isso
com a variável usual que se refere a string ou float Funciona somente dessa maneira. Então, aqui podemos ver claramente que Python trata a função como
um objeto de primeira classe e permite que variáveis como grit sejam tratadas como nomes de funções quando fazem Vamos trazer a função
para ver o resultado. As funções Lambda
geralmente são usadas com
funções integradas , como
filtro MP ou classificação Vamos considerar a função de mapa. Em Python, a função map é uma função
incorporada usada para aplicar uma função específica a cada
item em um intervalo como staple ou set e retornar
um uterável com um resultado Podemos usar essa função
quando queremos realizar
a mesma operação em vários itens
na coleção. No meu caso, como
iterável, tenho uma lista
e, como função que
vou aplicar a essa lista,
escrevo a função Lambda Neste exemplo,
a função Lambda eleva ao quadrado cada número na lista Como você deve ter notado, eu
também usei a função de lista. Ao mapear a função MAP
com a função de lista, forço o
objeto do mapa a gerar todos os seus itens e
armazená-los em uma lista. Isso me permite ver a saída imediatamente e trabalhar com os resultados como qualquer outra lista. Se eu executar esse código, veremos o resultado
imediatamente de uma só vez. Deixe-me mostrar rapidamente como
seria esse código sem
usar uma função Lambda Vou usar a mesma lista de números, mas a reescrevo como
uma função normal Primeiro, eu reescrevo
a função Lambda
e a chamo Então eu inicializo a
variável ao quadrado, e ela será uma lista vazia Vou salvar aqui novos elementos. Em seguida, escrevo quatro
voltas, percorro todos os números da minha lista, faço com que sejam quadrados e
acrescento à nova Vamos trazer o resultado. Esses
devem ser os mesmos valores. Então, se todo mundo está
bem, aqui estamos. A função Lambda permitiu que todo esse código fosse executado
em uma única linha
e, às vezes, é
muito conveniente Vou
aumentar um pouco a lista. Vamos considerar o exemplo
com a função de filtro. A função de filtro também é
incorporada em Python
e é usada para filtrar itens de
uma lista iterável, e é usada para filtrar itens de como lista ou templo, com base em uma A sintaxe básica é
quase a mesma. Mas, nesse caso, usarei a expressão que
verificará se X é par, então definimos uma lista de
números contendo números inteiros Criamos uma função Lambda que verifica se um número é par Usamos o filtro para aplicar essa função Lambda em
todos os itens em números, que filtra a lista para
manter apenas números pares Em seguida, convertemos o resultado
filtrado em uma lista e o armazenamos
em números pares Por fim, imprimimos a
lista de números pares. Então, se eu executar esse código, veremos a nova lista
com apenas números pares. As funções Lambda em
Python são uma ferramenta poderosa que permite criar
pequenas Como as funções do Lambda
são anônimas, elas normalmente são usadas
para tarefas de curto prazo em que uma função não
precisa ser reutilizada
em outro lugar no código As funções do Lambda só podem
ter uma expressão, o que significa que você não pode incluir várias declarações ou lógica
complexa nelas. Isso os torna menos adequados
para tarefas que exigem várias etapas ou operações
detalhadas, nas quais é melhor
usar funções regulares. Mas as funções Lambda
são especialmente úteis na
programação funcional porque podem ser
usadas como argumentos em funções como
mapear, filtrar e reduzir Isso facilita a criação de um código
claro e conciso para transformar
e filtrar dados sem muitas linhas extras Então, por enquanto, tudo isso está
salvo na próxima lição.
25. Entendendo o escopo em Python: Bem vindos de volta, pessoal.
Nesta lição, exploraremos o que significa
escopo em Python e definiremos imediatamente que há escopo variável
e resolução de escopo O escopo variável é um conceito
fundamental em programação que determina
onde a variável pode ser acessada e sua vida útil no O escopo define onde uma
variável pode ser acessada. Uma variável declarada
dentro de um escopo específico não
é visível ou acessível
fora desse escopo. Por exemplo, uma
variável definida dentro de uma função não pode ser acessada
de fora dessa função. E chamamos isso de escopo local. A vida útil de uma variável é a duração pela qual
ela existe na memória. Uma variável permanece
existindo e pode ser acessada desde que esteja
dentro do escopo definido. Quando a
execução do programa deixa o escopo em que a
variável foi definida, a variável normalmente fica indisponível, liberando memória Temos quatro tipos de escopo
e, em geral, ele
tem a abreviatura LGB Significa escopo local. As variáveis declaradas dentro de uma
função ou bloco são locais para essa função ou bloco e só
podem ser acessadas lá. Em seguida, temos o escopo delimitado nos
casos em que uma função é definida dentro de outra função A função interna pode acessar variável da função
externa. Então, temos escopo global. As variáveis declaradas no nível
superior de um script ou módulo podem ser acessadas de
qualquer parte desse modelo, incluindo funções internas
e escopo incorporado. Alguns nomes são predefinidos
pela linguagem de programação
e estão sempre acessíveis, como funções e constantes como N ou print em Python Ao definir claramente onde
as variáveis podem ser usadas, escopo ajuda a evitar
situações em que duas variáveis com o mesmo nome possam causar confusão ou erros
no programa. A compreensão do escopo
facilita a leitura e a
compreensão do código pois os desenvolvedores podem determinar
rapidamente onde e como as variáveis
estão sendo usadas. Vamos continuar praticando. Vamos imaginar que eu tenha
duas funções simples. Eu escrevo a primeira função e
aqui eu defini a variável A. Então eu escrevo a
segunda função, e aqui eu defini a variável B. Essas duas funções
imprimem suas variáveis. Se eu chamar essas duas funções
e depois executar o código, veremos essas
variáveis no console. Mas e se eu quiser imprimir a variável
A na segunda função? Quando eu chamo a segunda função, isso gera um erro de
nome porque a variável A não está definida no escopo
da segunda função. Eu defini no escopo
da primeira função, então não podemos usá-la aqui. Em um Python, quando uma
variável é referenciada, o interpretador a
procura em uma ordem específica, partindo do escopo
mais local e avançando até
encontrar a Esse pedido geralmente é
chamado de regra LEGB. Na segunda função, o Python tenta imprimir a variável A.
No entanto,
A não é encontrado
no escopo local,
então o Python se move para o escopo
global para pesquisar A.
Mas como A não está definido
globalmente, o
Python gera um Python Aqui, analisamos o escopo local. Vamos explorar mais. Vou renomear as funções para maior clareza e
adicionarei um recuo para fazer com que a segunda função fique aninhada
na
primeira e observarei como o
sublinhado do aviso de erro
na variável A Isso ocorre porque agora
temos um escopo delimitador e a função interna
pode ter acesso ao A. Se eu executar esse código, ele funcionará A variável A é definida
na função externa. Isso significa que A está delimitando o
escopo da função interna, tornando-a acessível
à função interna, mesmo que A não esteja definido diretamente dentro
da função interna Agora vamos considerar o escopo global. Aqui eu defini a
variável global A com o valor 33. Então eu criei duas
funções, a função um e a função
dois, que trazem essa variável Observe que a inicialização da variável A não está presente na função
em si, mas na função de impressão, ela não está sublinhada como um erro Agora, eu chamo essas duas
funções e executo esse código. Quando a função um é chamada, ela imprime o valor
de A, que é 33. Quando a função dois é chamada, ela também imprime o mesmo valor
de A, que permanece 33. É por isso que temos
duas variáveis idênticas aqui no console. Mas se eu definir A
dentro de cada função, cada função criará
sua própria variável local A. Essas variáveis locais
sombrearão a variável global, e isso significa que
a função agora referência às suas próprias versões
de A em vez da global. E se eu executar esse código agora, veremos uma imagem totalmente
diferente. A função um imprimirá sua variável local e é 22, e a função dois
imprimirá sua
variável local que é 11. Mas deixe-me remover a
variável local para a função dois. Agora, se eu executar esse código, a função dois imprimirá
o A que é igual a 33
porque a função um diz somente a variável local A
que é igual a 22, mas na função dois,
não há nenhuma variável local Isso significa que quando print é
chamado dentro da função dois, Bython segue sua regra LEGB
usual para resolver o nome da variável Como não há
A local na função dois, Python verifica o escopo
global em seguida, onde encontra A igual a 33 Em Python, a palavra-chave global é usada para especificar
que uma variável dentro de uma função
deve se referir a uma variável global em vez
de criar uma local Então, se eu aqui
na função um, escrever a palavra-chave global, vou fazer essa
variável como global. Quando eu uso o global
dentro de uma função, eu digo ao Python para usar a
variável do escopo global e permitir modificações nessa variável global de
dentro da Então, aqui na função um, a variável A igual a 22 modifica o A global
que era igual a E se eu executar esse código, veremos que a saída é
22 porque na função dois, não
temos nenhuma
variável local, e a função pesquisa a variável
no escopo global. Mas na função um, modificamos a variável global A para
que tenhamos 22, duas vezes. Mas modificar variáveis globais diretamente dentro da função geralmente
é considerada uma prática
inadequada na programação Uma abordagem melhor é
passar variáveis como argumentos para funcionar e
retornar quaisquer valores modificados. Compreender o escopo da variável é essencial para escrever um código claro, sustentável e eficiente Em Python, o escopo define onde a variável
pode ser acessada ou modificada com níveis
distintos, como local e fechamento
global e incorporado Essa hierarquia determina como o Python pesquisa
variáveis dentro da função , das
funções aninhadas Por enquanto, isso é tudo. Nos
vemos na próxima aula.
26. Manipulando erros com try-except nas funções Python: Bem vindos de volta, pessoal.
Já encontramos erros várias
vezes ao executar o código, que foi exibido
no console. No desenvolvimento de aplicativos,
é importante
lidar com esses erros e não
exibi-los ao usuário. Em vez de mostrar mensagens de erro de
linha, os desenvolvedores devem implementar
um mecanismo de tratamento para fornecer mensagens
fáceis de usar. Isso não apenas melhora
a experiência do usuário, mas também protege informações
confidenciais que podem ser expostas
por meio da mensagem de erro. tratamento adequado de erros pode ajudar a manter a estabilidade
do aplicativo e
orientar os usuários na resolução problemas sem revelar detalhes
técnicos E agora
aprenderemos sobre o
tratamento de erros na construção try and
accept. Vamos começar com
um exemplo simples para ilustrar melhor
como isso funciona Por exemplo, vou
tentar dividir por zero. Vou escrever uma
função regular que pega dois números e
executa a divisão. Em seguida,
inicializo o resultado da variável, chamada de função, e,
eventualmente, imprimo o resultado Se eu executar o código,
receberei um erro indicando que a divisão
por zero não é permitida. Agora vamos usar a construção
para lidar com esse erro. O bloco seco contém o código que queremos tentar executar. No meu caso, será divisão. Então eu tenho um bloqueio, exceto. Esse bloco contém o código
que manipula o erro. Esse bloco detectará qualquer exceção que ocorra
no bloco trib Aqui, a
divisão da função tenta
dividir A por B dentro de
um bloco tribal Então, quando eu chamo a divisão
com três e zero, a função tenta executar
três dividir por zero. Em pan, dividir por zero
gera zero erro de divisão. Como a divisão por
zero resulta em um erro, o controle do programa
salta imediatamente para o bloco de exceção No meu caso, o bloco except não especifica nenhum tipo de exceção
específico, como, por exemplo, erro de divisão
zero. Em vez disso, ele captura
todas as exceções que possam ocorrer
no bloco triplo Quando o erro ocorre, o bloco de exceção
executa e imprime a mensagem. O erro ocorreu e
não pode ser dividido por zero Esta é uma mensagem amigável projetada para informar ao usuário que a operação não pôde ser concluída devido à
divisão por erro zero. Vamos executar o código
para verificar isso. Nesse caso, não veremos a mensagem de
erro usual de rastreamento do Python Em vez das informações de
erro técnico, o usuário vê uma mensagem amigável indicando o que deu errado. Eu substituo zero por um
e executo o código novamente, e não vejo nada porque esqueci de
imprimir o resultado Isso é muito melhor.
Agora tudo funciona. Em geral, pedimos
ao programa que tente executar
esse bloco de código. Se algo deu errado, explicamos isso para o usuário, e as exceções do Python
são eventos que interrompem o fluxo normal da execução
do programa Python fornece um
rico conjunto de
construções em classes de exceção que representam várias condições de
erro Ao usar classes de
exceção específicas, você pode detectar e lidar com
erros de forma eficaz. Por exemplo, no meu caso, posso reescrever esse
código dessa forma Aqui eu uso erro de divisão zero. Esse conjunto de códigos me permite
armazenar a instância de exceção em uma variável E. Essa variável me dá
acesso a detalhes sobre as exceções, como tipo e qualquer mensagem de
erro associada Ele pode ser útil para
registrar, depurar ou fornecer uma
resposta mais informativa ao usuário A exceção de
erro de divisão zero é gerada porque a divisão
por zero não é permitida Ao capturá-lo com
esse bloco de código, atribuo a
exceção real à variável E. Agora E contém a mensagem de erro que explica por que
o erro ocorreu. Mas ao especificar o erro de divisão
zero, deixamos claro que
estamos lidando apenas com a
divisão por zero erros Isso evita capturar
acidentalmente outras exceções que possam
ser geradas, como erro de tipo, erro nome ou qualquer outro erro não relacionado à Por exemplo, se eu passar por
engano uma string
em vez de um número, o Python geraria e digitaria
error Meu bloco de código
ignoraria isso e deixaria
o programa falhar. Porque neste exemplo, devemos usar erro de tipo
no bloco de exceção. Nesse caso, usar erro de tipo no bloco except
é útil porque ajuda a lidar com
casos em que uma ou ambas as entradas da função
são do tipo errado Também podemos usar vários blocos de
exceção para lidar com diferentes tipos de exceção
em um único bloco triplo Vamos reescrever essa parte do código. Isso é útil porque
diferentes tipos de erros podem exigir tratamento
diferente, especificando
vários blocos de exceção, cada um para uma classe de
exceção diferente Podemos lidar com cada tipo de erro de
uma forma que faça sentido
para esse erro específico. Aqui, lidamos com as
situações com divisão
zero e erro
de tipo separadamente. Essa abordagem tem
várias vantagens. Cada tipo de exceção tem
seu próprio tratamento específico, para que o programa possa responder adequadamente a
diferentes erros Cada bloco pode imprimir ou
registrar mensagens específicas, facilitando a
compreensão do que deu errado. E, finalmente, ao
especificar exceções, garantimos que somente
os erros relevantes sejam detectados e tratados, deixando outros possíveis
erros sem tratamento, para que
possam ser
corrigidos ou tratados possam ser garantimos que somente
os erros relevantes
sejam detectados e tratados,
deixando outros possíveis
erros sem tratamento, para que
possam ser
corrigidos ou tratados separadamente.
Mas isso não é tudo. A
construção completa de tratamento de erros se parece com isso. Também temos Ls e, finalmente,
blocos Ls são executados, se nenhuma exceção foi
levantada no bloco tri Finalmente, bloco que
é executado de qualquer maneira,
independentemente de uma exceção
ter sido gerada ou não, vamos considerar um exemplo. Então aqui eu escrevo o bloco L. Ele é executado somente se nenhuma exceção for levantada
no bloco trib Aqui, simplesmente
imprime que a divisão foi bem-sucedida para indicar que
a operação foi bem-sucedida Em seguida, adiciono o bloco final. Ele é executado
independentemente de uma exceção
ter ocorrido ou não. Ele imprimirá
a execução da função de divisão
concluída para indicar
o final da função. Observe que a declaração de impressão
no bloco s agora tem
uma cor diferente. Isso ocorre porque esse
bloco deve ser executado somente se nenhum
erro for gerado. No entanto, no bloco triplo acima, temos uma declaração de retorno Isso significa que, se não
houver erros, simplesmente
retornaremos
o resultado imediatamente e o bloco s
nunca será executado. Portanto, inicializamos o resultado
da variável aqui. Agora que temos a
construção completa, vamos testá-la. A primeira vez que temos tipos
incompatíveis. Nesse caso, recebemos
a mensagem
do bloco de exceção
com erro de tipo e temos a mensagem
do bloco final. Se eu substituir por zero, recebemos a mensagem
do segundo bloco de exceção
e do bloco final. Vamos testar a entrada válida. Eu substituo zero por um. Nesse caso, nenhuma
exceção foi levantada no trilog e
o
bloco s foi executado, é
claro, bloco final Portanto, em Python,
há uma grande variedade de exceções de construção que podem ser usadas para lidar com Essas exceções abrangem uma
variedade de tipos de erros, incluindo
erros lógicos, erros de tempo de execução
e erros relacionados ao sistema lista completa dessas exceções de
construção pode ser encontrada na documentação oficial do
Pattern Vamos resumir essa
construção brevemente. Use o Triblog para empacotar o código
que pode gerar uma exceção. Utilize o bloco de exceções para capturar exceções
específicas e
tratá-las adequadamente. Use o bloco Else
para códigos que devem ser executados somente se nenhuma
exceção ocorrer Use o bloco final
para tarefas de limpeza. Isso deve acontecer independentemente
de um erro ter ocorrido ou não. Ao entender e utilizar
esse mecanismo de tratamento de exceções, você pode escrever um código
mais limpo, legível e
sustentável Posteriormente, na seção OP, aprenderemos como criar classes
personalizadas para tratamento
de erros. Por enquanto, isso é tudo. Nos vemos na próxima aula.
27. Introdução aos módulos em Python: como trabalhar com eles e usar a declaração de importação: Bem vindos de volta, pessoal. Vamos
explorar o que são módulos, como criá-los e
como trabalhar com eles. Em Python, os módulos são uma forma de
organizar e reutilizar código. Um módulo é simplesmente um
arquivo contendo definições e
declarações do
Python, como funções, classes ou variáveis,
que podem ser importadas e usadas em outros programas em
Python Os módulos ajudam a
estruturar seu código e a mantê-lo limpo,
sustentável e modular Para usar um módulo, você
precisa importá-lo para seu script Python atual
usando a instrução import Vamos ver como isso funciona
com o exemplo. Trabalharemos com três arquivos Python
separados. Esses arquivos estão localizados em um único diretório raiz
chamado Projeto um. Vamos criar o Projeto Spacewar. Este será um programa
desenvolvido para gerenciar e exibir estatísticas de
jogadores para
um jogo funcional chamado Space Wars. O projeto é
dividido em três módulos, como eu disse antes.
Primeiro, estatísticas do jogo. Este módulo conterá
funções para calcular a pontuação de
um jogador com base em suas conquistas
e na pontuação do jogo, e também
determinará sua classificação Em seguida, jogador Utils. Este módulo fornece
funções utilitárias para criar perfis de
jogadores e formatar suas estatísticas de jogo
em formato legível E o terceiro arquivo main dot pi. Esse é o arquivo principal que
une tudo. Ele cria um perfil de jogador,
recupera suas estatísticas e exibe um resumo
formatado, incluindo sua classificação e pontuação Aqui, aprenderemos como
usar módulos Python, onde cada módulo
é responsável por uma parte específica da
funcionalidade e como
importar e usar
funções e constantes de outros módulos para criar
um Vamos começar com as estatísticas do jogo. Este módulo conterá
duas funções importantes:
calcular a pontuação e obter o degrau A string doc explica
o que a função faz. Ele calcula a pontuação do jogador com base em suas conquistas
e na pontuação do jogo Já sabemos que
as sequências de documentos são escritas entre aspas
triplas e normalmente são colocadas imediatamente após a definição da
função ou classe Então eu crio a função de calcular
pontuação. Ele usa dois argumentos, conquistas e pontuação, e calcula a pontuação dividindo as conquistas
pela Se a pontuação for nula, o jogador recebe uma
pontuação de bônus com base nas conquistas E aqui eu uso o
bônus de comando para escopo zero. É um exemplo de um comando de
linha única em Python. Comandos de linha única
são usados para explicar uma linha ou
seção específica do código. Isso ajuda os desenvolvedores a entender o que essa parte do código está fazendo. Isso é especialmente útil quando a lógica pode ser complexa, não óbvia ou quando você deseja fornecer contexto adicional
para uma operação específica. Se a pontuação não for igual a zero, retornamos
o cálculo da pontuação do jogador com base em suas conquistas A rodada é uma função embutida
em Python. Isso arredonda o
número de ponto flutuante para o inteiro mais próximo. Então eu crio a segunda
função, obtenho Rank. Essa função
pegará um argumento, pontuará esse argumento, obteremos da função
calcular pontuação. Lembro que essa
função retorna esse valor. Aqui eu também crio uma string de documentos. A classificação variará de
iniciante a profissional. Vou adicionar um emoji para
um exemplo mais visual. A pontuação é comparada com
uma série de limites, 200, 150 e 100 E dependendo do
valor da pontuação, a classificação
correspondente é retornada. Essas classificações são representadas
por uma sequência que
inclui o nome da classificação e um emoji para
representar visualmente a classificação Em seguida, uso o comentário
novamente para indicar que as seguintes variáveis são constantes e definidas
no nível do módulo. Em Python, as constantes geralmente são escritas em cada caso.
Nós já sabemos disso. Constantes são valores
que devem
permanecer inalterados durante a
execução do programa A primeira constante representa o valor padrão das conquistas de um
jogador. É útil para inicializar perfis de
jogadores quando nenhuma conquista
foi conquistada ainda. Por exemplo, quando um novo
jogador inicia o jogo, suas conquistas podem ser definidas
como zero como ponto reto. A segunda constante representa a pontuação padrão de um jogador. Semelhante às conquistas padrão, esse valor inicializa
a pontuação de
um jogador em zero quando ele começa a
jogar, supondo que ele ainda não tenha
marcado nenhum ponto A terceira constante armazena
o nome do jogo. Vamos reutilizar essas constantes
em todo o projeto. O segundo módulo é
responsável por criar perfis de
jogadores e
formatar estatísticas de jogadores Na primeira linha de código, usamos uma instrução de importação que é usada para trazer variáveis de
função ou classes de um módulo para outro, para que possam ser
usadas no script atual. From como palavra-chave, usada para especificar o módulo
do qual você deseja importar. Estatísticas de jogo no
nome do módulo. Quero importar
de, no meu caso, gaming statts dot pi é um arquivo Python
que contém funções e constantes relacionadas ao cálculo de pontuações
e à Na verdade, as estatísticas
de jogo do módulo podem conter várias
funções ou constantes. Estamos importando especificamente
apenas alguns itens dele. Você pode pensar nisso como
selecionar o que você precisa
do módulo em vez de trazer o módulo inteiro para
o script atual. Aqui, eu crio uma função,
crio um perfil de jogador. Serão necessários dois
argumentos: nome e idade. Adicione uma corda para cães. Lá dentro, eu crio
um dicionário que armazena informações do jogador,
como nome, idade, jogos jogados
e obtenção de status. Nome, este é o nome do jogador, idade, é a idade dos jogadores. Então, temos jogos disputados zero. Isso define o valor padrão de quantos jogos o jogador
jogou como zero, o
que significa que o jogador
é novo ou
ainda não
jogou nenhum jogo. É ativo, verdadeiro. Isso define o
status do jogador como ativo, o
que significa que os jogadores
estão atualmente ativos no jogo. Em seguida, crio a função
formatar estatísticas do jogador. Serão necessários três argumentos, nomes de conquistas e
pontuação. Crie docstring Docstring era para a função, e isso em linha de comando, eu criei para explicar
o propósito das seguintes linhas
de código, onde
a função
calcula a
pontuação e recebe Essa função
formata as
estatísticas dos jogadores em um formato
legível por humanos, que pode ser exibido
para o jogador usado em relatórios ou registrado
para fins de rastreamento Então, eu calculo a pontuação usando a função calcular pontuação
importada das estatísticas do jogo. Essa função calcula a pontuação calculada do
jogador com base na lógica definida
no módulo de estatísticas do jogo Aqui usamos os
argumentos que obtemos. Esses argumentos foram definidos
na função calcular pontuação
no módulo de estatísticas de jogo. Aqui nós apenas o usamos. Em seguida, a função Get rank é chamada com a pontuação
calculada. Também foi importado do módulo de estatísticas de
jogos. Com base na pontuação, a função retorna uma classificação,
como profissional, especialista ou assim por diante, dependendo dos limites definidos no módulo de estatísticas do
jogo A função retorna
uma string formatada contendo as estatísticas dos
jogadores Aqui, usamos uma string de
várias linhas formatada para criar um bloco de texto legível e bem
estruturado Isso significa que a string
pode abranger várias linhas, o que é especialmente útil para formatar grandes blocos de texto, como mensagens de relatório Já sabemos o que é a formatação de
string F. Eu não vou repetir isso.
Trabalhamos com isso. Como resultado,
formatamos a mensagem. E, finalmente, meu módulo. Primeiro, eu importo
módulos e funções. Primeira linha, importe funções
específicas, calcule a pontuação e obtenha o degrau Ao importar elementos específicos, você pode usá-los
diretamente em seu código sem precisar
prefixá-los com o nome do módulo Também importo o nome constante do jogo também do módulo de estatísticas do jogo. A segunda linha importa
todo o módulo Player Utils. Para usar qualquer função ou
variável desse módulo, você precisa prefixá-la com
o nome do módulo player Utils Quando usamos a entrada seletiva
como a primeira linha de código, ela economiza a digitação e melhora a legibilidade
do código, permitindo acesso
direto a
funções É útil quando você só precisa de uma parte
específica de um módulo. entrada completa do módulo
mantém o espaço de nomes organizado, exigindo que você
prefixe o nome do módulo Isso ajuda a evitar colisões de
nomes se módulos
diferentes tiverem
funções com os mesmos nomes Então, aqui estou criando
a função principal. Essa função é o ponto de
entrada do script e coordena a
execução de várias tarefas. Crie um comando para
o entendimento. Nesta linha de código, crie um dicionário que represente
o perfil do usuário. Observe que o dicionário é criado usando a função create
player profile, que podemos chamar
do módulo importado. Como importamos
o módulo inteiro, acessamos essa função usando o nome do módulo seguido por
um ponto e o nome da função. Aqui passamos o nome de
Nik e 25 anos. O perfil inclui o valor
padrão, como jogos jogados zero
e está ativo como verdadeiro. Em seguida, exibo uma mensagem de
boas-vindas usando o nome constante do jogo importado do módulo de estatísticas de
jogos. E aqui eu apenas
imprimo a linha de traços para separar visualmente
as seções da saída Aqui eu defino valores de exemplo para as
conquistas e a pontuação do jogador. conquistas
representam o número de conquistas conquistadas
pelo jogador e a pontuação representa uma métrica relacionada ao desempenho do
jogador, como o número de jogos
disputados ou a classificação de desempenho. Aqui eu chamo a função de
formato de estatísticas do jogador. Essa função importada
do módulo Player Utils
usa o nome, as
conquistas e a
pontuação do jogador como argumentos O motivo pelo qual usamos o nome do
módulo antes da função é porque
importamos o módulo inteiro. Como eu disse antes, ao
importar o módulo inteiro, todas as funções
definidas dentro dele
precisam ser acessadas usando o nome do
módulo seguido por um ponto E aqui obtemos o nome
acessando um valor de um dicionário
escrevendo o nome do jogador, estamos acessando
o
valor associado ao nome da chave no dicionário, que neste caso
seria Nick. Ele usa
as funções de calcular
pontuação e executar Gt do jogo
para gerar um relatório formatado, que então retorna
como uma string de várias linhas E então eu imprimo o resultado. Eu envio as
estatísticas formatadas do player para o console, vamos demonstrar o
uso direto das funções importadas Aqui eu chamo a função
de
calcular pontuação do módulo de fornecimento de estatísticas, que foi importado no
início do script. Aqui, conquistas, o número de conquistas
que o jogador conquistou. E marque uma métrica de desempenho, como o número de jogos
disputados ou a pontuação da linha. Dentro da função calcular
pontuação, temos a fórmula. Essa fórmula divide o
número de conquistas pela pontuação e multiplica
o resultado por 100 Em seguida, arredonda o resultado
para o número inteiro mais próximo. Isso fornece uma pontuação
calculada com base nas
conquistas e no desempenho do jogador. Em seguida, chamo a
função G Runk, usada para determinar a classificação do jogador com base na pontuação calculada A classificação é determinada pelo valor
da pontuação calculada
passado para essa função. Aqui, a função verifica
a pontuação calculada em relação a vários limites
e atribui a classificação Em seguida, imprimimos a
classificação do jogador usando uma string F. Vou lembrá-lo de que essas
duas funções mencionadas acima foram importadas
do módulo de estatísticas de jogos separadamente. Portanto, ao chamar
essas funções, não
usamos o
nome do módulo com um ponto. Podemos usar essa função
diretamente sem o prefixo do módulo. Essa é uma das construções mais
importantes em Python. É usado para controlar como a tela do
Python se comporta
quando executada diretamente
ou importada Nome com sublinhado duplo é uma
variável de construção em Python Isso recebe um valor dependendo de como o
script está sendo usado. Quando executo um
script Python diretamente, a variação do nome é
automaticamente definida como main Se o script estiver sendo
importado para outro script Python, Import main e assim por diante, como fizemos antes
, o valor do nome será definido como o nome
do próprio módulo Nesse caso, main, a condição que
vemos nessa linha de
código é uma forma de
verificar se o script
Python está sendo executado diretamente ou
importado como um módulo Se o script estiver sendo
executado diretamente, e eu vou
executá-lo diretamente, nome será igual a main, então a condição se tornará verdadeira. Se o script estiver sendo importado como um módulo para outro script, name será o nome
do módulo de script. Então, a condição se torna falsa. Eu coloco o
código de execução principal dentro da estrutura. Isso garante que o código seja executado
somente quando o script for executado diretamente e não
quando for importado para outro lugar. Isso evita a execução indesejada de
código quando o módulo é importado. O código será executado somente quando o script
for executado diretamente. Gente, recapitulação rápida. Um módulo em Python é
um arquivo simples com extensão
Pi que contém código
Python,
incluindo funções,
variáveis incluindo funções, Em nosso exemplo,
temos três módulos, estatísticas de
jogo,
utilitários do jogador e principal Organizar o código em módulos ajuda a manter seu
programa organizado. Você pode importar um módulo inteiro usando a sintaxe do nome do
módulo Importar Ou, como alternativa, você pode
importar funções ou
variáveis específicas de um módulo usando from module name,
Import functions name. Isso permite que você use o nome completo do módulo ou
apenas o nome da função. Mas isso não está tudo no padrão. Você pode importar módulos,
funções, classes ou variáveis usando um alias Isso permite que você dê um
nome mais curto ou mais conveniente a um item importante, o que pode ser particularmente
útil ao trabalhar com nomes de módulos
longos ou se você
precisar evitar conflitos de nomes. Você pode importar módulos inteiros, funções
ou variáveis
específicas usando a palavra-chave as para
atribuir um alias É comumente usado
em grandes projetos que módulos ou funções podem ter nomes longos ou quando você deseja manter seu
código limpo e legível Usar aliases em importações é uma prática
padrão em
Python que melhora a eficiência
da codificação e
melhora a legibilidade do código , especialmente ao trabalhar com bibliotecas de terceiros Então pessoal, até
a próxima aula.
28. Usando decoradores como padrões de design em Python: como implementá-los e aplicá-los: Bem vindos de volta, pessoal. Vamos dar uma
olhada nos decoradores. No padrão, os decoradores são uma ferramenta
poderosa e versátil que permite modificar o
comportamento de uma função ou classe Basicamente, existem funções que envolvem outra
função para estender, ou melhor, sua funcionalidade sem modificar diretamente o código de outras
funções originais Pense nos decoradores como
invólucros que você pode colocar em torno de uma função
para aprimorar seu comportamento Vamos ver como isso
funciona no exemplo. Um decorador é simplesmente
uma função que usa outra função como argumento e retorna uma nova função Na primeira etapa, defino uma função decoradora que usa outra função
como argumento Em seguida, defino uma função de
invólucro interno
dentro da função decoradora Aqui eu imprimo uma mensagem porque wrapper adicionará
algumas funcionalidades e eu vou mostrá-la Essa mensagem indicará
que agrupamos a função, chamamos a função original
de dentro do invólucro, porque é um invólucro,
então vou adicionar
algum comportamento após a chamada da
função Eu imprimo outra mensagem
que
indicará que função estava chamando
e retornaria a função wrapper Aqui está o que está acontecendo aqui. Meu decorador é uma função
decoradora que
usa uma função funk como argumento
e, dentro do meu decorador,
um e, dentro do meu decorador, novo wrapper de função
é definido onde eu chamo a função funk original e
adiciono adiciono Finalmente, meu decorador retorna
a função wrapper. Seu primeiro decorador simples
está pronto. Vamos usá-lo. Vou aplicar
esse decorador a
outra função
usando a sintaxe add Aqui eu defino a função, diga olá, função simples
que imprime hello world. E eu uso meu decorador. No final, estou
chamando a função. Se eu executar esse código,
receberemos essa mensagem. Podemos ver aqui que a
mensagem impressa por nossas funções say hello é encapsulada com duas mensagens adicionais
do decorador No entanto, usar a
sintaxe de adição é opcional. O que a sintaxe faz é simplesmente um atalho
para o seguinte Esse código funcionará da
mesma forma que vimos anteriormente. O Python passa automaticamente a função say hello para a função
decoradora M. O mesmo dizer olá agora se refere a essa nova função
decorada. E em vez de usar a sintaxe do decorador
add M, você passa explicitamente a
função para o Essa linha pega a função halo
original e a passa como argumento
para o decorador M. Meu decorador retorna uma
nova versão decorada da função hello E se eu executar esse código, podemos ver o mesmo resultado. Mas a sintaxe de adição é mais
concisa e legível. Portanto, para os próximos exemplos, usarei a sintaxe add Eu comento o código anterior
e começo a escrever um novo. Meu primeiro passo é importar o tempo. Essa linha insere
o módulo de tempo, que fornece várias funções relacionadas ao
tempo Nesse caso,
usarei o método time para medir o tempo antes e
depois da execução da função. Este temporizador de função
será uma função decoradora. Ela usa uma função
funk como argumento. Essa é a função que
queremos decorar ou modificar. A função timer retorna
uma função de wrapper que substituirá o funk quando
o decorador Essa função de invólucro
adiciona funcionalidade. Nesse caso, medindo
o tempo gasto pelo funk em torno da função
original função Wrapper
usa todos os argumentos
e argumentos de palavras-chave
que o funk receberia Isso permite que o decorador trabalhe com qualquer assinatura de
função Definimos a hora de início, depois chamamos a
função original e definimos a hora de término
e, em seguida, imprimimos
o tempo decorrido Finalmente, ele retorna o
resultado da função
e, no final,
a função timer
retorna a função wrapper Essa é a parte fundamental
do decorador, porque agora a
borracha será usada no lugar do
funk original. Então, vamos testá-lo. O cronômetro de linha acima da função
slow é uma abreviatura
para aplicar A função lenta é uma função Python
simples
que executa duas tarefas,
simula um atraso usando o lapso de
tempo e imprime
uma mensagem indicando que
a função que executa duas tarefas, simula um atraso usando lapso de
tempo e imprime uma mensagem indicando que
a A função time slip faz parte do módulo de tempo
integrado do Python Ele pausa a execução
do programa pelo número
especificado de segundos. Nesse caso, eu
escolho 2 segundos. Isso significa que quando eu
chamo a função lenta, o programa
escorrega ou não faz nada por 2 segundos antes de
prosseguir para a próxima linha Quando eu chamo a função slow, B realmente chama a função wrapper
retornada pelo decorador do temporizador. A hora de início é registrada antes de chamar a função lenta
original. Em seguida, a função lenta é executada. Isso faz com que
o programa durma por 2 segundos. Após a conclusão da função lenta, a hora de término é registrada O tempo de lapso é
calculado e impresso mostrando quanto tempo a
função lenta demorou para ser executada Então, se eu executar esse código,
obteremos o resultado. A
função de primeira linha concluída indica a
função executada. Na segunda linha,
o tempo gasto é aproximadamente 2 segundos,
refletindo a duração do sono O Python também vem com vários degradadores
integrados na seção OOP.
Veremos os degradadores integrados do Python
em Veremos os degradadores integrados do Python Por enquanto, isso é tudo. Nos
vemos na próxima palestra.
29. Criando um gerador de códigos QR para redes sociais com Python: Agora vamos combinar o aprendizado com a prática e criar
algo útil. Hoje em dia, quase todo mundo tem um site pessoal
ou presença on-line. Seja no Instagram, no
YouTube ou em
outra plataforma, se você possui uma empresa,
por exemplo, talvez
precise de um código QR para ajudar as pessoas a
acessar rapidamente seus recursos A maioria das pessoas está
familiarizada com os códigos QR, mas aqui está um lembrete rápido
para quem não O código QR é um código de barras
bidimensional que pode ser digitalizado por smartphone ou QScanner
composto por quadrados pretos sobre fundo
branco. Ele armazena vários tipos de
informações, como texto,
links, números de telefone Os códigos QR são populares por sua conveniência
e versatilidade Se você estiver compartilhando detalhes de
contato ou informações sobre produtos, eles oferecem uma solução rápida com potencial
adicional de marketing e
promoção. Vamos começar. Eu criei um arquivo em que, usando o Python, geraremos um código
QR vinculado ao canal ao vivo do meu
programa digital Você pode usar isso
para qualquer recurso. Seu site,
página específica, se você escolher, usará o código QR da biblioteca
Python, que é uma
ferramenta poderosa para gerar QR diretamente no E primeiro, instalaremos a
biblioteca usando o Comando, instalaremos o código QR do
PIP
e, em seguida, inseriremos o código QR em seguida, inseriremos Aqui temos a mensagem. Houve um erro ao verificar
a versão mais recente do PIP. Geralmente aparece quando instalador de pacotes do
PIP Python tenta verificar se uma versão mais recente
de si mesmo Esse erro não é crítico
e não impedirá que você use o PIP para
instalar ou gerenciar pacotes Significa simplesmente que o PIP não
conseguiu verificar sua
própria versão mais recente, mas ainda
funcionará normalmente para instalar, atualizar ou desinstalar
pacotes conforme necessário Não tem
impacto no meu fluxo de trabalho, então, por enquanto, deixo como está. Agora vamos escrever uma função
chamada Gerar código QR. Essa função
aceitará argumentos
como dados, é nosso conteúdo. Nome do arquivo e correção de erros. F dois argumentos são posicionais e o terceiro é argumento
de palavra-chave O parâmetro de dados será o link do recurso que
queremos codificar,
enquanto a correção de erros
definirá o nível de correção de erros
, o que afeta a
resiliência dos códigos QR Vou torná-lo um pouco legível. Quando cada parâmetro
está em sua própria linha, fica mais fácil escanear e identificar argumentos
individuais. A biblioteca de códigos QR em Python inclui configurações de correção de
erros , que gerenciam
quantos dados no código QR podem ser recuperados se parte
dele estiver danificada ou obscurecida Ele oferece quatro níveis. Baixo, recupera até
7% dos dados, médio, até 15%, quartil e Usaremos o baixo nível
de correção de erros capaz de recuperar
até 7% dos dados danificados Por enquanto, é o suficiente. Em seguida, definirei o tamanho da caixa. Esse parâmetro define o tamanho em pixels de cada
quadrado individual na grade do código QR. Um tamanho de caixa maior torna cada quadrado
no código QR maior, resultando em uma imagem
geral maior, seja dez, e esse parâmetro especifica a espessura da borda branca ao redor do código
QR medida Por padrão, uma borda de quatro
é recomendada para garantir que os scanners possam distinguir facilmente o código QR do plano de fundo Em seguida, dentro da função, inicializei a variável QR e criei um objeto de código QR adicionei nossos dados na biblioteca de códigos QR.
O código QR é uma classe básica
usada para criar e personalizar códigos usada para criar Essa classe fornece
a estrutura e funcionalidade necessárias para
definir o conteúdo, o
design e o nível de
correção de erros dos códigos QR design e o nível de
correção de erros Ao criar o objeto do código
QR, passamos a correção de erros, tamanho da
caixa e a borda
como argumentos de palavra-chave Como esses argumentos são
fornecidos na chamada da função, eles serão usados no
objeto de código QR com os valores que definimos Não se preocupe Abordaremos quais classes estão
em toda a seção P. Por enquanto, o principal é
entender como as funções
e as bibliotecas funcionam. Então eu chamo a função Adicionar dados. Essa função permite que você adicione o conteúdo ou dados reais como URL ou texto, que você
deseja codificar no código QR. Você pode adicionar
vários dados com essa função e o
código QR armazenará tudo isso Então eu uso a função M. Essa função gera
a imagem do código QR com base nos dados fornecidos Quando o ajuste do parâmetro
é igual a verdadeiro, o código QR
ajusta automaticamente seu tamanho
para alimentar os dados,
garantindo que todas as informações sejam
armazenadas sem estouro ou truncamento armazenadas sem estouro Em seguida, a
função make image gera um objeto de imagem de código QR com base
nos dados e configurações previamente definidos
no objeto de código QR. Parâmetros que temos aqui, a primeira
cor de preenchimento. Eu o coloquei preto. Ele define a cor do
código QR em si, os quadrados. O segundo parâmetro,
cor do fundo, eu o defino em branco. Ele define a cor de fundo
por trás dos quadrados do código QR. Eventualmente, nós o salvamos. O argumento filename especifica os caminhos e o nome do arquivo,
incluindo Já abordamos
essa construção de código nas lições anteriores. Essa linha de código garante que o código seja executado somente quando
executado diretamente, não se for importado como um módulo. Em seguida, chamaremos nossa função e passaremos todas as informações. A chamada de função aqui gera um código QR vinculado
a uma URL específica No meu, pois é o link do meu canal. E eu o salvo como código QR PNG. Então, aqui temos o código que demonstra os princípios de
programação funcional ao encapsular o processo de geração de
código QR
em uma única função,
gerar código em uma única função, Ao colocar todas as etapas nas funções de geração de
código QR, o código é reutilizável Vamos verificar se funciona. Agora, se eu executar esse código, terei um arquivo. Se eu abri-lo, vou
ver nosso código QR. Vamos testá-lo. Enquanto funciona. Tente criar seu próprio código QR. Você pode usar qualquer link que
quiser e praticar. Você pode tentar gerar um código QR para o seu perfil
do Instagram, por exemplo, por
enquanto, só isso Nos vemos na próxima aula.
30. Introdução à programação orientada a objetos (OOP) em Python: cursos e objetos: Bem vindos de volta, pessoal.
Parabéns. passando para a parte mais
importante do aprendizado da programação orientada a objetos em
Python, ou P. Esse conceito poderoso
ajudará você a escrever um código
mais limpo e organizado e a tornar
seu programa mais flexível Aproveite o processo de aprendizado. Em Python, tudo
é um objeto. Isso significa que cada
dado em Python, seja um número, uma string, uma lista ou até mesmo uma função, é tratado como um objeto No OP, um programa é
composto por uma coleção de objetos que interagem entre si para realizar tarefas. A programação orientada a objetos
oferece várias vantagens. Um dos principais benefícios
é que o OOP ajuda a organizar melhor o código
e encapsulá-lo Ao agrupar dados e
métodos relacionados em um objeto, seu código se torna mais modular
e fácil de manter Outra vantagem do OOP é que ele permite a criação
de código reutilizável Ao definir classes que podem ser instanciadas
em objetos, você pode criar código
que pode ser usado em diferentes partes de um programa
ou em vários Em Python, todo P é
implementado por meio de classes. As classes definem as propriedades
e os comportamentos de um objeto. Enquanto objetos são instâncias de classes que contêm
dados e métodos. Podemos pensar em uma classe como um modelo para
criar objetos Eles definem os atributos
e métodos de estrutura
e comportamento que os objetos
criados a partir deles terão. Método, por outro lado, são funções definidas dentro de
uma classe que descreve ações ou comportamentos
específicos que
esse objeto pode realizar. Assim, a classe define o esquema, enquanto os métodos definem ações para o objeto criado a
partir desse esquema, você pode pensar em um objeto como uma entidade do mundo real que tem
características e Vamos dar um exemplo simples
para ilustrar esse conceito. Vamos criar uma
classe simples chamada cachorro. Será o plano
para as instâncias. Vou criar mais tarde. Aqui eu uso o método it. É uma função especial
chamada construtor. Ele é executado automaticamente sempre que você cria um novo objeto
ou instância da classe. Aqui eu passo os
parâmetros nome e idade. Self a se refere ao
objeto específico que está sendo criado, para que você possa atribuir dados
especificamente a esse objeto. Essas duas linhas de código, nome
próprio é igual ao nome
e idade própria é igual à idade Crie dois atributos nome e idade e defina seus valores com
base nos argumentos fornecidos. Isso permite que cada
instância da classe tenha seus próprios valores de nome
e idade. Você verá isso em um minuto. Em seguida, eu crio a
função bark. Essa função
na classe dog é um método que define um comportamento para instâncias
da classe dog. Essa é uma
função simples que retorna. Agora temos nossa
primeira aula simples. Esta é a nossa planta. Em seguida, vou criar uma
instância a partir desse blueprint. Eu inicializei a variável meu cachorro. Então eu chamo meu cão de classe
recém-criado com os seguintes parâmetros. Serão Lu e três anos. Quando ligo para essa linha, acontece
o seguinte. O Python aloca memória
para um novo objeto dog, e o construtor do método net, como eu disse antes, Aqui temos o
nome próprio que será Lu e a idade própria que
será de três anos. O parâmetro self
permite que o método
se refira à instância
que está sendo criada, possibilitando
definir seus atributos. O método init é executado somente uma vez durante a
criação de um objeto Isso significa que cada vez você cria uma nova
instância de dog, o método it é executado para inicializar essa instância específica com
os atributos fornecidos No meu caso, o nome e a idade do
cachorro, mas podem ser atributos
diferentes. Então, aqui, a instância dog
recém-criada é atribuída à
variável my dog. Quando criei uma instância de dog e a armazenei
na minha variável dog, posso chamar seu método. Essa linha de código
chama o método bark, que retorna a
string e a imprime. Vamos executar o código
e ver o resultado. Quando quiser chamar um
método em uma instância, use a notação de pontos Isso significa que, para acessar qualquer método ou atributo
da instância, você sempre usa o nome da
instância seguido por um ponto e, em seguida, o nome do
método ou atributo. Também quero chamar
sua atenção para o fato de que, ao
inicializar uma instância, você deve fornecer todos
os argumentos necessários especificados no construtor Caso contrário, você
encontrará um erro. Vamos considerar os atributos da classe. Esses atributos podem ser compartilhados
em todas as instâncias de uma classe e podem ser acessados usando o
nome da classe ou por meio de uma instância. No meu exemplo de classe Dog, o atributo de classe species
tem o valor canino Vou adicionar as informações do método. Onde vou usar
todos os três atributos, um deles será atributo de
classe e outros dois
serão nosso nome e idade. Só para mostrar qual é a diferença entre
esses atributos. O parâmetro self
permite que o método
acesse a instância específica
na qual foi chamado, possibilitando recuperar os atributos
da instância,
como nome e idade E aqui eu uso espécies próprias. Nesse caso, ele se refere
à string keine. Como a espécie é definida
como um atributo de classe, cada instância de cão pode
acessá-la por meio da própria espécie, mesmo que seja definida
no nível da classe. Então, o que vou fazer a seguir criar duas instâncias
da classe de cães, que sejam um pouco baixas e rígidas. Em seguida, imprimo as informações em
que usamos todos os parâmetros. Eu imprimo informações sobre você
e informações sobre Rik. Quase esqueci o
segundo atributo que definimos no construtor Agora, se eu executar esse código, receberemos duas mensagens
para cada instância. E, como podemos ver,
temos nomes diferentes, anos
diferentes, mas
a mesma espécie. Isso porque espécie
é um atributo de classe. Já vimos que podemos chamar o método
usando a notação de pontos Em Python, também podemos acessar
atributos em um objeto,
tanto atributos de instância quanto atributos de classe,
e podemos fazer isso também
usando a notação de pontos Isso significa que escrevemos o nome
da instância ou da
classe seguido por um ponto e, em seguida, o nome
do atributo. Olha isso. Eu chamei o
atributo de classe em duas instâncias. E se eu executar esse código, podemos ver que eu
tenho espécies duas vezes, e duas vezes eram nove. Isso ocorre porque a espécie
é o atributo da classe e todas as instâncias de cães
compartilham esse valor. Mas o nome do atributo e a
idade são criados dentro do método init usando
self name e self age Esses são atributos de instância, o que significa que são específicos para
cada instância do cão. Acessar o nome por meio de
instâncias meu cachorro e meu cachorro dois
nos dará dois nomes diferentes. Mas é importante
entender a diferença entre atributos de classe
e atributos de instância. E a principal diferença: os atributos de
classe estão acessíveis tanto na
classe quanto em suas instâncias, como vimos antes, aqui eu
chamo atributo de
classe na classe e tudo funciona. Os atributos da instância
só podem ser acessados por meio instâncias
individuais, pois representam dados exclusivos
de cada instância .
Tentar acessar atributos
específicos como nome ou cada diretor da classe, retornará um erro porque esses atributos não
existem no nível da classe. Eles só são criados quando uma instância específica
é inicializada Então, agora abordamos
quais óculos, instâncias de
Wan e conhecemos os atributos de classe
e atributos de instância. Também consideramos
o método NIT. O método NIT é
um método especial, às vezes chamado de método
mágico, que é chamado
automaticamente
quando uma nova instância de um vidro é criada Da mesma forma, antes que um
objeto seja destruído, um destruidor é chamado, que em Python é Esse é
outro método mágico. Mas como o intérprete
gerencia
automaticamente a liberação dos
recursos usados pelo objeto, ter um destruidor
não é muito importante Portanto, não vou me
aprofundar nesse método agora. Não vamos nos concentrar em
métodos mágicos em detalhes no momento. Nós os abordaremos
mais profundamente mais tarde. Por enquanto, é essencial
entender que init é o
método construtor usado para inicializar cada instância
com os valores
ou configurações exclusivos em que o
objeto Quando você cria uma
instância de um vidro, Python procura automaticamente o método init na classe Esse método geralmente usa
self como parâmetro, que representa a
instância que está sendo criada junto com outros parâmetros para
configurar a instância
com dados específicos. A última coisa que mencionarei nesta lição é que, em Python, nomes das
classes são convencionalmente escritos em uma Esse estilo é conhecido
como estojo de camelo. Por exemplo, os nomes das classes
podem ser escritos como cães, pessoas ou espécies animais. Essa capitalização
ajuda a distinguir os nomes das
classes de outras
variáveis ou funções, que normalmente começam
com uma letra minúscula Na próxima lição,
exploraremos os diferentes tipos de
métodos nas aulas. Então, por enquanto, tudo isso
é até a próxima lição.
31. OOP em Python: trabalhando com métodos de classe, estáticos e instância: Bem vindos de volta, pessoal.
Vamos continuar. Na programação orientada a objetos, especialmente em
linguagens como Python, as classes podem conter
diferentes tipos de métodos, métodos de instância, métodos de classe e
métodos estáticos Vamos começar com os métodos de
instância. Esses são os
tipos de métodos mais comuns nas aulas. Eles operam em uma
instância da classe, um objeto, e podem acessar e modificar os atributos da
instância. Vimos isso na lição
anterior. Tínhamos métodos de latido e informação. Eles têm acesso aos atributos da
instância definidos no método it. E o primeiro parâmetro de um método de instância
normalmente é chamado self, que se refere à instância da classe que chama o método. Aqui posso dizer que o latido
não é um exemplo ideal, por exemplo, de método porque
não usamos aqui os atributos. Vou usar as informações para
mostrar como elas funcionam. Um método de instância em Python
pode acessar dados de
classe, atributos de nível de classe,
mas foi projetado principalmente para ser chamado em uma instância
da classe, não na classe Vou remover a chamada para o método bark.
E execute o código. Desculpe, esqueci o segundo atributo
e é importante É a idade. Agora funciona. Como eu disse antes, esse método tem acesso aos atributos da
classe. Mas se eu agora chamar esse método na classe,
receberei um erro. Sim, os métodos de instância
podem acessar os dados da classe, mas eles devem ser chamados na instância, não na classe em si. Na verdade, você pode
tecnicamente ligar para a aula.
Eu vou te mostrar como. No entanto, não é
recomendado,
pois não é um
padrão de uso típico para métodos de instância. Aqui, eu chamo o método in, por exemplo,
diretamente no cão da classe, mas passo manualmente para o
meu cachorro uma instância de dog como primeiro
argumento. Isso gera confusão porque os métodos de
instância são
projetados para operar em instâncias e chamá-los diretamente
na classe não indica
claramente esse comportamento. Então, eu não recomendo. Acabei de te mostrar como isso pode ser. Agora que abordamos isso, vamos passar para
os métodos de classe. Métodos de classe são
métodos que pertencem
à própria classe e
não a uma instância específica. O primeiro parâmetro
de um método de classe normalmente
é chamado de CLS, que se refere
à própria classe. Eles podem acessar e
modificar atributos de classe, variáveis definidas
no nível da classe. Eles são marcados com um método de classe
decorator. decorador em Python
é uma função especial que modifica o comportamento
de outra Nesse caso, o decorator é
usado para definir um método de classe. Quando você usa o método de classe, ele diz ao Python que o método deve receber
a própria classe, CLS como primeiro argumento Em vez de uma instância
da classe self, isso permite que o método acesse e modifique dados em nível de
classe, mas não dados específicos da instância. Veja como podemos
chamar esse método. Ao usar o
nome da classe diretamente, estamos chamando um método
no nível da classe. Em seguida, o operador de ponto, usado para acessar atributos ou métodos
dentro de uma classe ou instância, e então o método de classe obtém partes que definimos
na classe de pontos. No final, o parêntese que usamos para
chamar o método Sem parênteses,
essa linha de código seria apenas uma referência
ao método em si,
mas não o chamaria de fato Então, quando eu executo esse código, Biton localiza a classe de cães Ele usa o
método Get species na classe dog porque o método class permite que ele seja chamado
na própria classe. Get species é executado com a classe dog como
argumento CLS. O método executa
sua função, que normalmente
envolve o retorno um atributo de nível de classe. No meu caso, é espécie, e depois imprimimos o resultado. Então, chamamos o método de classe
na classe cão dois ou três com o atributo de
nível de classe compartilhado. Vamos continuar com o método estático. Esses são métodos que não modificam o estado do vidro
ou da instância. Eles são definidos usando o decorador de método
estático. Primeiro, devolvo o
método de latido que tínhamos antes. Neste exemplo, posso
converter o método bark em
um método estático adicionando
o decorador de método estático Esse é um excelente
exemplo porque método
bark não
precisa acessar ou modificar nenhum dado
específico da instância
ou qualquer dado específico da classe. Portanto, os métodos estáticos são
ideais para funções que executam tarefas independentemente
do estado da classe. Pode ser algo como funções
utilitárias ou auxiliares. Ao marcar o método bark com o decorador de método
estático, estou indicando que
esse método não requer referência a uma
instância ou à própria classe Portanto, eu não tenho aqui argumentos
próprios ou CLS. Isso simplifica o Bark
e comunica a outros desenvolvedores que é
uma função autônoma, não depende de nenhum dado
dentro da classe ou das instâncias Posso ligar para Bark diretamente
na aula de cães. E também ainda posso chamar
latido de um exemplo de cachorro. Primeiro, eu crio uma
instância da classe dog
e, em seguida, chamo o
método estático nessa instância. Independentemente de como
chamamos um método estático, obtemos o mesmo resultado. Vamos resumir, os métodos de
instância são o tipo mais comum de métodos
na programação
orientada a objetos Eles operam em uma instância
da classe e têm acesso
aos atributos da instância
e a outros métodos da instância. O primeiro parâmetro de um método de
instância
geralmente é self. Isso se refere à instância da classe
na qual o
método é chamado, permitindo que o método
acesse e modifique os atributos da instância. Em Python, o
parâmetro self não é uma palavra-chave e pode ser tecnicamente
substituído por qualquer nome No entanto, é uma convenção amplamente
aceita usar self no nome do primeiro parâmetro do método de
instância. Isso porque ajuda a melhorar
a legibilidade do código e deixa claro que o método opera em uma
instância da classe Então, temos métodos de classe. Esses são métodos
vinculados
à própria classe e
não a uma instância. Eles são usados para operações
que afetam a classe. O primeiro parâmetro de um
método de classe geralmente é CLS, que se refere
à própria classe. Isso permite que o método
modifique os atributos do nível da classe. Em métodos de classe, o
CLS é uma convenção, assim como self é usado
em métodos de instância Refere-se à própria classe, pois usar self é
importante para maior clareza e consistência ao lidar
com dados de instância. Seguir a convenção
CLS nos métodos de
classe é
considerado a melhor prática Esses métodos são úteis
quando você precisa operar ou modificar dados compartilhados entre todas as
instâncias da classe. Os métodos de classe podem
ser chamados tanto
na própria classe
quanto em uma instância. Mas esse comportamento geralmente
não é necessário. Isso é possível porque os métodos de
classe estão vinculados à classe e
não a uma instância, o que significa que eles
podem ser acessados tanto
da classe
quanto da instância. Às vezes, pode ser mais conveniente chamar um
método de classe em uma instância, especialmente se você já estiver trabalhando com uma
instância e quiser acessar um método em nível de classe sem se referir
ao nome da classe. Mas, normalmente, os
métodos de classe devem ser chamados na própria classe,
não em uma instância. Então, temos métodos estáticos. Esses são métodos que não dependem dos dados da classe
ou da instância. Eles são completamente
independentes e não têm acesso à
instância ou classe. Podemos usá-lo para
funções utilitárias
relacionadas à classe, mas que não dependem de seu estado. Os métodos estáticos não usam o CLS ou o self como primeiro argumento Eles são independentes. Podemos chamar esses métodos tanto na classe quanto em uma instância. Embora normalmente eles sejam
chamados diretamente para a classe. Cada tipo de método serve
a uma finalidade específica. Métodos de instância para
interagir com dados de objetos, métodos de
classe para dados em nível e métodos estáticos para funções
utilitárias que não dependem de atributos de classe ou
instância Ao entender
essas diferenças, você pode estruturar melhor
suas classes e métodos. Então, por hoje, isso é
tudo, até a próxima lição.
32. OOP em Python: herança única e múltipla explicadas: Bem vindos de volta, pessoal.
Estudamos o que é uma classe, o que é um objeto de classe e os tipos de
métodos nas classes. Agora é hora de se
familiarizar com um dos principais conceitos
de herança
OOP Ao explicar a
herança em Python, é útil começar com
o conceito fundamental de que todas as classes em
Python herdam de uma classe raiz construída na classe chamada object é útil começar com
o conceito fundamental de que
todas as classes em
Python herdam de uma classe raiz construída na classe chamada object. Entender isso ajuda a esclarecer
a estrutura da
herança de classes em Python,
especialmente porque todas as classes,
mesmo aquelas que não herdam
explicitamente de
nenhuma outra classe especialmente porque todas as classes, mesmo aquelas que não , ainda derivam do objeto. Em Python, objeto é a classe mais fundamental da qual todas as outras classes herdam
implicitamente Isso significa que cada classe em Python é uma subclasse de objeto,
tornando o objeto a raiz da hierarquia de classes do
Python Como todas as classes, em última análise,
derivam do objeto, a classe do objeto está sempre
no topo de qualquer hierarquia de
herança Antes de mostrar e
provar isso para você, vamos cobrir um pouco da história. Python, houve uma mudança
significativa no design das classes
com o lançamento do
Python 2.2, quando o conceito novas classes
de estilo Antes do Python 2.2, o Python só tinha o que chamávamos Eles eram mais simples e
não herdavam da classe de objeto
raiz Em vez disso, eles formaram sua
própria hierarquia de classes separada. Todas as classes de estilo não são mais usadas
no Python moderno Python três, o conceito de classes de estilo
antigo foi
completamente removido Portanto, todas as classes agora têm
um novo estilo por padrão. O Python 2.2 introduziu
novas classes de estilo como uma melhoria em relação às classes de estilo
antigo A maior mudança foi que todas as novas classes de estilo são
herdadas do objeto, criando um
modelo de objeto unificado em que tudo, tanto as classes
definidas pelo usuário quanto os tipos construídos, faziam parte da mesma hierarquia de
herança Quando o Python 3 foi lançado, os designers do
Python decidiram criar
todas as novas classes de estilo Isso significa que no Python 3, o conceito de classe de estilo antigo
foi completamente removido Qualquer classe definida no Python três herda do
objeto automaticamente, mesmo que não o
declare explicitamente . Agora,
escrever a classe I
e a classe I herdada do
objeto são equivalentes no
Python três, ambas criando novas classes objeto são equivalentes no
Python três herda do
objeto automaticamente,
mesmo que não o
declare explicitamente. Agora,
escrever a classe I
e a classe I herdada do
objeto são equivalentes no
Python três, ambas criando novas classes de estilo. Ao criar classes,
podemos herdar explicitamente do objeto para esclarecer que nossa classe é
derivada da classe raiz Isso geralmente é feito para garantir a compatibilidade com o
Python dois e o Python três Você pode encontrar essa necessidade ao trabalhar em um projeto
antigo. Se você não sabe o que é, projeto e
programação
legados se referem a um sistema de software ou
aplicativos mais antigos que
ainda estão em uso, geralmente sem tecnologia de dados ou código que exija
manutenção ou atualizações. Vamos começar com a herança
única. Vou criar duas classes, o animal e o cachorro. O animal terá um método de
instância, basta comer. A classe dos cães
herda da classe dos animais. E também temos uma
instância do método bark. herança única ocorre quando uma subclasse herda de apenas uma superclasse Chamamos a classe principal
de superclasse. No nosso caso, é animal. A classe animal pode ser um modelo geral
ou classe base
e, em nosso exemplo
, representa qualquer tipo
de animal que possa comer. Podemos imaginar outros
animais, como gatos,
leões, que poderiam
herdar esse comportamento Em seguida, definimos a classe de cães que herda da classe animal Isso significa que o cão
terá automaticamente todas as propriedades e
métodos da classe animal. Dentro da classe de cães, existe um novo método, latir. Esse método imprime latidos
herdando de um animal. cão não apenas
herda a capacidade de comer, mas também pode ter seu próprio
comportamento, como latir Aqui podemos ver a
herança e extensão do método. cão obtém o método
de comer da classe animal
e, além disso, o cão define
um método único de latir, específico para cães. Agora, eu crio uma instância
da classe cachorro porque o cachorro
herda do animal O cão também é considerado
uma instância de animal, o que significa que ele pode acessar todos os métodos e
atributos do animal, bem
como aqueles definidos
especificamente no cão. Então, aqui estou chamando o método
inherit eat. Essa linha de código
chama o método eat. Como cachorro é uma instância de cachorro e cachorro
herda de um animal, Python busca primeiro o método de
comer no Em seguida, o Python sobe na cadeia de
herança até o animal da classe mãe, onde
o encontra e o
executa E aqui eu chamo o método do latido, que é definido diretamente
na classe dos cães. Como o método bark é
exclusivo da classe dog, Python não precisa verificar o animal da classe
principal para esse Ele chama diretamente o latido do cachorro, e aqui temos o resultado. Aqui definimos o método
bark na subclasse. Esse método é específico
para a classe de cães e não existe no animal da classe
parental. Então, aqui chamamos o
método It herdado da classe animal, e aqui chamamos
o método da casca Isso foi definido especificamente
na classe de cães. Vamos continuar com a herança
múltipla. herança múltipla
é um recurso na programação orientada a objetos Isso permite que uma classe
herde de mais de uma classe principal Na linguagem Python, a
herança múltipla é suportada, que significa que você pode criar
uma classe que herda atributos e métodos Estenderei as classes de
animais e cães introduzindo uma nova
classe chamada PAT, que representa comportamentos
específicos de animais de estimação, como brincar Em seguida, usaremos a herança
múltipla para criar uma classe de cães Isso herda
tanto do animal quanto do animal de estimação. Então, agora o que temos, temos a classe animal
que tem um método,
que imprime comer quando chamada. Essa classe representa um comportamento
geral comum a todos os animais, como a capacidade de comer. Então, temos uma classe de animais de estimação que tem um método de jogo,
que imprime o jogo. Essa classe representa
o comportamento específico dos animais de estimação, como a habilidade de brincar. Temos a aula de cães. Essa classe herda
tanto do animal quanto do animal de estimação. Isso permite que o cão herde métodos tanto do animal quanto do
animal de estimação, para que ele tenha acesso a
eles do animal e às
brincadeiras do animal de estimação Além disso, o cão define
um método único de latido, que é específico para cães e não está presente em
nenhuma das classes parentais. Em seguida, criamos
uma instância da classe de cães. Como o cão herda
tanto do animal quanto do animal de estimação, a instância do cão
terá acesso aos métodos de ambas as classes, bem
como ao seu próprio método latido Aqui já
temos o método E, nós o chamamos, depois
chamamos o método bark, e agora eu apenas adiciono o método play. O método da classe PED. Como eu disse antes, como o cão
também herda do PED, ele também pode usar esse método. E se eu executar esse código, veremos claramente o resultado. Na herança múltipla, o Python
precisa de uma forma de determinar
a ordem em que
pesquisa métodos nas classes principais Essa ordem é conhecida como ordem de
resolução de método, MRO. O MRO define a sequência na qual o Python pesquisará métodos
e atributos Neste exemplo,
a classe dog procurará primeiro um método em sua própria
classe, depois em animal e,
finalmente, em PAT Seguindo o pedido, eles são listados na declaração da
classe Dog. Você pode ver o MRO
de uma classe usando o atributo MRO ou o método MRO
como este, eu vou te mostrar Aqui vemos o cachorro. Primeiro, o animal, o
segundo, o terceiro, vemos o vidro PAD
e, no final, o objeto da classe. Por que a ordem é importante? Se tanto o animal quanto o animal de estimação definirem um método com o mesmo
nome, que seja correto. O Python usaria o MRO para
determinar qual deles chamar. O Python usa a
linearização C três, também chamada de algoritmo de linearização da
superclasse C três para
estabelecer a ordem da para Então aqui eu defini dois métodos
idênticos, som, e aqui eu
chamo esse método. O MRO para cães,
neste caso, será cão,
animal, animal de estimação e objeto Então, o Python encontra e executa primeiro o
som no animal. Por enquanto, isso é tudo. Nos
vemos na próxima aula.
33. OOP em Python: herança multinível e hierárquica: Bem vindos de volta, pessoal.
Na lição anterior, aprendemos sobre herança
única
e herança múltipla Também aprendemos sobre a ordem de resolução do
método, que determina a ordem na qual as classes base são pesquisadas
ao executar um método Agora vou explicar o que é herança
multinível. herança multinível
é um tipo de herança em que uma classe
é derivada de outra classe,
que já é derivada de alguma outra classe já é Isso forma uma cadeia de
herança em que cada classe
subsequente herda
de sua predecessora Por exemplo, animal
é a classe base. mamífero herda do animal, tornando-o uma classe derivada cão herda do mamífero, o que o torna uma
subclasse de mamífero e indiretamente Vamos agora escrever isso
na forma de código. Aqui eu estendo as classes de
animais e cães
e adiciono a classe mamífero Então, aqui eu tenho o animal
como classe base. Tem um único método ET. Qualquer classe que herda de animal terá acesso
a esse método ET Então eu criei mamífero uma subclasse que
herda Ao herdar do animal, a classe dos mamíferos obtém todas as
funcionalidades do animal, que significa que o mamífero tem
acesso ao método Além disso, o mamífero
define um novo método chamado respiração, que
produz E, eventualmente, temos cães, uma classe que
herda dos mamíferos Como o mamífero herda do animal e o cão
herda do
mamífero, o cão herda
todos os métodos do mamífero e do
animal,
e o cão tem seu próprio todos os métodos do mamífero e do
animal,
e o cão tem Então, aqui eu criei
uma instância de cachorro. O objeto dog tem acesso a todos os métodos definidos
em sua hierarquia de classes, que inclui métodos de
cachorro, mamífero e O primeiro que eu chamo de método eat, Python verifica se o cachorro
tem um método eat Se não for encontrado,
aparece nos mamíferos, a classe parental dos cães Se também não for encontrado lá, parece em animal, a classe parental dos mamíferos O Mod é encontrado em animais, então comer é impresso. Em seguida, chamo o método da respiração. O Python verifica se o cão
tem um método de respiração. Se não for encontrado, aparece em
mamíferos. O método foi encontrado. Mamífero, então a respiração também é impressa e, com o
método da casca, é muito fácil O método é
definido diretamente
na classe dog. Aqui
temos latidos Podemos ver a ordem de
resolução do método usando o método Amro Na explicação anterior, usamos MRO para verificar a ordem de resolução do
método da classe Dog usando
o
método MRO com Ambas as abordagens fornecem
as mesmas informações de MRO, mas em estruturas de
dados diferentes Isso pode afetar a
forma como você trabalha com os resultados, como
iterá-los ou modificá-los, porque o primeiro retorna
algumas classes E no nosso caso agora, ele retorna uma lista de classes. Então, depende do que
você vai fazer a seguir. Vamos voltar à herança de
vários níveis. E vai ser bom de usar. herança de vários níveis
permite agrupar logicamente Por exemplo, todos os
animais podem comer, mas somente os mamíferos podem respirar. Você pode estender facilmente a hierarquia adicionando
mais subclasses Por exemplo, poderíamos
adicionar uma classe de gato que também herda de um mamífero, mas tem
seus próprios comportamentos específicos herança de vários níveis permite que
você construa uma cadeia de
classes em que cada classe
herda de sua É útil para criar uma hierarquia de
classes estruturada e reutilizável, mas deve ser usada com
cuidado para Outro tipo de herança que
eu gostaria de
apresentar é a herança
hierárquica herança hierárquica é
um tipo de herança em que várias
subclasses A herança hierárquica é
um tipo de herança em
que várias
subclasses herdam de uma única classe principal. Isso significa que um pai de
classe base pode ter vários filhos de
classes derivadas que herdam seus
atributos e métodos Por exemplo, aqui, o animal na classe base, classe parental, gato e cachorro são subclasses Tanto o gato quanto o cachorro
compartilham as propriedades dos animais, mas também têm
seus próprios métodos exclusivos. Vamos dar uma olhada
nisso na prática. Então, aqui eu removi a classe
mamífero e adicionei a classe gato. animal será a classe dos
pais
tanto para a classe de gatos quanto para a classe de cães. O gato é uma classe derivada que
herda do animal. Isso significa que o gato tem acesso
automático a todos os métodos definidos no método
animal like eat. Além disso, cat define
seu próprio método, Mo. Na classe de cães, substituo
mamífero
por animal porque o cão é
outra classe derivada que herda do Assim como o gato, a classe dos cães também herda o
método de comer do animal
e, além disso, o cão define seu próprio método
exclusivo de latido Em seguida, crio a instância
da classe de cães. O objeto cão pode chamar o
método de comer herdado do animal e também pode chamar
seu próprio método de latido Em seguida, crio uma instância
da classe cat e o objeto cat também pode chamar o ID do método que foi
herdado do animal e também pode chamar
seu próprio método Mu Como podemos ver, as classes de
cães e gatos herdam o
método de comer da classe animal Isso permite a reutilização de anúncios. O método de comer é definido apenas
uma vez na classe animal, mas pode ser usado por qualquer subclasse Embora tanto o gato quanto o cachorro
compartilhem o método de comer, cada classe também tem seu próprio método
exclusivo, quilômetro e latido. Isso permite que cada
subclasse tenha comportamentos
específicos, além da funcionalidade compartilhada Essa estrutura promove
uma hierarquia clara em que várias subclasses podem estender a funcionalidade de
uma única classe base Isso facilita o gerenciamento de classes
relacionadas que compartilham
algum comportamento comum, mas também têm seus próprios comportamentos
distintos. Métodos e
atributos comuns podem ser definidos
na classe base e
reutilizados por todas as subclasses Isso reduz a duplicação de código e melhora herança hierárquica permite agrupar logicamente classes Mas devemos lembrar que as subclasses estão fortemente
acopladas à classe base Se os
animais da classe base mudarem, todas as subclasses, gato,
cachorro, podem ser afetadas Se uma subclasse precisar
substituir um método
da classe base,
isso pode causar confusão, isso pode causar confusão, especialmente se não for
documentada adequadamente Aqui continuaremos
com o método de escrita, o que é e como
podemos fazer isso. Nos vemos na próxima aula.
34. OOP em Python: composição: Bem vindos de volta, pessoal. Agora vamos falar sobre composição e OP. Na programação orientada a objetos, composição
operacional é um princípio de
design em uma classe é composta
por um ou mais objetos
de outras classes. Isso é conseguido incluindo
instâncias de uma classe dentro de outra classe como seus atributos em vez de usar herança Quando aprendemos a herança, vimos claramente que esses
modelos são um relacionamento Por exemplo, um cachorro é um animal. Ele permite que uma classe herde atributos e métodos
de outra classe Na composição, temos
modelos que têm uma relação. Por exemplo, um carro
tem um motor. Em vez de herdar
de outra classe, a classe principal contém uma
instância de outra classe Vamos ver isso usando o código da lição
anterior. Eu reescrevo um pouco
meu exemplo original para usar composição
em vez de herança A classe animal
permanece a mesma antes com um
atributo de nome e seu método. Em vez de herdar
de um animal, a classe cão agora
contém uma instância
da classe animal como um
atributo, animal próprio Agora, o animal próprio é um
atributo da classe dos cães. Esse atributo é atribuído uma instância da classe animal. Ao criar essa instância, passamos name como argumento
para o
método init das classes animals porque a classe animal espera um parâmetro name
quando é inicializada Isso significa que, quando criamos uma nova instância animal
dentro da classe dog, devemos fornecer um valor de nome, que será usado para definir o atributo self name
dessa instância animal. Como a classe dog cria uma instância animal durante
sua própria inicialização, a classe dog também deve
aceitar um parâmetro name É por isso que as aulas de cães. O método se parece com isso. Aqui nós adicionamos o nome. Ao criar um objeto de cachorro, agora
você precisa fornecer um nome, uma idade e uma raça. A classe dos cães tem seus
próprios atributos, como idade e raça, além
do atributo animal. Na classe dos cães, temos um atributo animal próprio que contém uma instância
da classe animal. Self animal name acessa o atributo name
da instância animal
contida no objeto dog Nós o usamos em uma string formatada para produzir uma mensagem
personalizada Ao chamarmos de autoalimentação animal, estamos delegando o comportamento
alimentar
à instância animal
contida no objeto do cão Quando eu crio uma
instância de cachorro, eu passo o nome, a
idade e a raça. O nome é usado para
criar um objeto animal, que a classe dog
usa internamente Então, depois de tudo isso, quais
benefícios obtivemos? Mudanças na classe animal têm menos probabilidade de
impactar a classe dos cães. Você pode facilmente
trocar ou modificar o comportamento da classe de animais
sem afetar a classe de cães Por exemplo, você pode
substituir o animal por outra classe ou adicionar mais funcionalidades sem
alterar a classe do cão. Ao usar a composição, você está seguindo o princípio da
responsabilidade única. O
princípio da responsabilidade única afirma que uma classe deve ter
apenas uma responsabilidade ou motivo para mudar. Isso significa que cada classe deve se concentrar em uma única tarefa
ou funcionalidade, facilitando o
entendimento, a manutenção
e a extensão do código . A classe animal é
responsável pelo comportamento geral dos animais, enquanto a classe dos cães lida com a lógica específica dos
cães. Com a herança, a classe dos cães estava fortemente ligada
à classe dos animais Se a classe de animais mudar, isso pode quebrar a classe de cães. Também tivemos menos flexibilidade. É mais difícil mudar
ou ampliar o comportamento, especialmente se você tiver uma hierarquia de herança
profunda Mostrei um exemplo de
composição refatorando o
código do animal e do cão para que você pudesse entender melhor a diferença entre
as abordagens No entanto, o exemplo com animal e cachorro não é o mais adequado porque a relação
entre um cão e animal é mais adequada
para herança Composição é quando construímos um objeto a partir de componentes
diferentes. É como um carro feito
de várias peças. Agora imagine que você precisa
escrever código do zero, onde você
aplicaria a composição. Vamos criar um exemplo muito
simples de composição usando um cenário de carro
e motor. Neste exemplo, a classe do carro usará uma instância
da classe do motor. A classe do motor tem
um atributo de tipo e um método de início para imprimir uma
mensagem quando o motor arranca. Essa classe é independente e pode ser reutilizada em outros contextos Então, temos uma classe de carro que tem um atributo de modelo e
um atributo de motor. Em vez de herdar
do motor, ele contém uma
instância do motor A classe de carros tem seu
próprio método de partida. Eu criei uma instância
da classe do motor. Em seguida, crio um objeto de carro com o modelo Mustang e o objeto de
motor criado anteriormente
e, em seguida, chamo o método start Esse método chamou
o objeto do carro. Se eu executar esse código, receberei a mensagem
iniciando o carro Mustang Por enquanto, na classe de carros, temos o atributo automotor, mas não é apenas um atributo. É uma variável de instância. Isso foi inicializado quando
um objeto de carro foi criado. Esse motor automático
contém uma referência a um objeto de motor que foi passado como argumento
para o construtor do carro Quando criamos uma instância
da classe car, fornecemos um objeto engine
para o parâmetro engine, e esse objeto engine é então atribuído ao
atributo self engine da instância car. Como resultado,
motor automático se refere
ao objeto motor que foi
passado quando o carro foi criado. Depois que o objeto motor é atribuído ao atributo
automotor, a linha de partida automática do motor chama o método de
partida do objeto motor armazenado no motor automático. Este é um exemplo
de delegação, em que uma classe de carro delega a tarefa de ligar o
motor para a classe do motor E aqui vemos que depois que o
método de partida dos motores é executado, essa linha é executada
na própria classe de carros. Ele imprime uma mensagem indicando
que o carro está dando partida, incluindo o modelo do carro. Ao passar o motor como parâmetro durante a
criação do objeto do carro, você ganha flexibilidade em como e quando o
objeto do motor é criado. Talvez você queira criar
um motor personalizado ou modificá-lo antes de
passá-lo para o carro. Por exemplo, você pode adicionar configuração
extra
ao motor antes de usá-lo no carro. Se a criação do
motor for feita separadamente, você poderá ter mais controle
sobre seu ciclo de vida. Por exemplo, você
pode decidir reutilizar o mesmo motor em vários carros sem
duplicar a lógica de criação Vamos resumir e
identificar todas as vantagens e desvantagens da herança
e composição de ambas as abordagens Vamos começar pela herança. Os modelos de herança
são um relacionamento, o
que significa que a classe secundária é
um tipo da classe principal Por exemplo, se você
tem um animal de classe e um cão de classe que
herda de um animal, então o cachorro é um animal Isso implica que a
subclasse deve ser capaz de fazer tudo o que a classe mãe
pode fazer e possivelmente mais É um
relacionamento hierárquico em que a subclasse é uma versão
especializada
da Os modelos de composição
têm um relacionamento, o que significa que uma classe tem outra classe como parte
de sua estrutura. Por exemplo, o carro tem um motor. O carro não é o
tipo de motor, mas usa um motor
como um de seus componentes. Isso significa que o objeto
composto como o motor de um carro, é apenas uma parte do orifício
maior e pode ser substituído ou trocado
independentemente da classe principal. A herança é menos
flexível porque vincula fortemente a classe infantil à
classe dos pais Qualquer alteração na classe principal pode afetar
todas as subclasses, dificultando a
modificação ou a extensão código sem afetar Por exemplo, se eu mudar um
método na classe animal, isso pode quebrar ou alterar o
comportamento da classe cão, especialmente se o
método for substituído A composição é mais flexível porque
acopla frouxamente os componentes A classe principal pode conter
e usar instâncias de outras classes sem depender de sua implementação
interna. Isso significa que você pode alterar ou
substituir
facilmente partes do seu
sistema, como
trocar um objeto do motor
em uma classe de carros, sem afetar o
comportamento geral da sua classe. A herança permite a
reutilização de código por meio de subclasses,
em que classe filha herda
métodos e atributos da classe métodos e Isso pode ser eficiente, mas também pode causar problemas
se a hierarquia ficar muito profunda ou se você herdar comportamentos
indesejados Por exemplo, se uma subclasse precisa
apenas de alguns métodos
da classe principal,
mas herda tudo, mas herda tudo, isso pode levar a uma complexidade
desnecessária A composição promove a reutilização de
código por meio da delegação de
objetos, o que significa que uma
classe pode delegar tarefas
específicas ao objeto
componente Isso permite combinar
funcionalidades de diferentes classes sem
herdar tudo Dessa forma, você pode misturar e combinar diferentes componentes para
criar novos comportamentos, tornando seu sistema mais
modular e reutilizável Quando usamos herança, as mudanças na classe principal têm um amplo impacto em
todas as Se você modificar o método
na classe principal, isso afetará todas as subclasses
que herdam esse método, o
que pode introduzir bugs
ou comportamentos inesperados Na composição, as mudanças
são mais isoladas. Como as classes são
independentes e se comunicam por meio de suas interfaces
públicas, a modificação de um componente
não afeta diretamente os outros. Portanto, a herança é
melhor usada quando você tem uma relação hierárquica
clara Como o pássaro é um animal ou o
gerente é um funcionário. É adequado quando você deseja tirar proveito do polimorfismo, como nos casos em as subclasses compartilham muito comportamento com a classe
principal, mas também podem estender ou Composição ideal para
casos em que você deseja criar comportamentos
complexos
combinando objetos
independentes simples. Por exemplo, um robô que tem várias
peças intercambiáveis, como bateria ou braços É ótimo para cenários
em que você deseja seguir o
princípio de responsabilidade única e manter seu sistema flexível,
modular e sustentável Espero ter explicado
a diferença em detalhes. Por enquanto, isso é tudo,
até a próxima lição.
35. OOP em Python: polimorfismo: Bem vindos de volta, pessoal. Vamos nos familiarizar com o
conceito de polimorfismo polimorfismo é um conceito
fundamental na
programação orientada a objetos que
permite que objetos de
diferentes classes sejam tratados como objetos
de Literalmente, significa muitas
formas e, em programação, refere-se à capacidade de
usar uma única interface ou método para representar diferentes
tipos ou comportamentos. Em Python, o polimorfismo
é implementado por meio da substituição do método e do
sobrealojamento do método No entanto, o Python
não suporta
sobrecarga de métodos diretamente, como algumas outras linguagens,
como Java, mas o polimorfismo ainda pode ser alcançado por meio de digitação dinâmica, algumas outras linguagens,
como Java,
mas o polimorfismo ainda pode ser
alcançado por meio de digitação dinâmica,
herança e método de escrita. Já sabemos que o método de escrita ocorre quando
uma subclasse fornece sua própria implementação
de um método que já está definido
em sua superclasse Em Python, o método da subclasse
substitui o método da
classe mãe,
mas ainda podemos chamar
o método da classe mãe usando a superfunção . Vamos detalhar isso
com um exemplo simples. Então eu começo definindo uma classe
base chamada animal. Dentro da classe animal, eu defino um som de método. Quando esse método é chamado, ele imprime na string algum som
genérico de animal. Esse método deve ser substituído por subclasses para fornecer sons
específicos
para diferentes tipos de animais Então eu crio a classe de cães e ela herda
da classe animal Nessa subclasse,
o método de som é substituído para imprimir som, que é específico para Quando criamos uma instância
da classe dog e chamamos
o método de som, ela imprime um woof em vez do som
genérico de animal definido
na classe animal Então eu defino a classe gato, que também
herda da classe animal E aqui também
temos o método de som. Da mesma forma que a classe de cães, a classe de gatos substitui
o método de som, mas desta vez para imprimir mio Eu crio uma lista chamada animais, que contém instâncias de
três classes diferentes, cachorro, gato e animal. Dog cria uma instância
da classe dog, onde o método de som imprime lobo. Cat cria uma instância
da classe cat,
onde o método de som imprime Mo e o animal
cria uma instância da classe animal em que o
método de som imprime algum som
genérico de animal. Eu examino a
lista de animais
e, para cada objeto, chamo o método do som. Sim, podemos fazer assim. Quando eu chamo o som animal, Python determina
dinamicamente o tipo real do objeto,
cachorro, gato ou animal em tempo de execução e invoca Isso é polimorfismo
ou método de pilotagem, em que o som do método se comporta maneira diferente com
base no tipo de objeto, embora seja chamado da mesma forma para todos os objetos, na
primeira iteração, primeira iteração, O primeiro objeto na lista é uma instância da classe dog. Na primeira iteração,
temos a instância dog. O método sonoro
do cachorro é chamado, então ele imprime madeira O segundo objeto na lista é uma instância da classe cat. Na segunda iteração, temos a instância cat O método sonoro do
gato imprime milhas. E o terceiro objeto é uma
instância da classe animal. Então, na terceira iteração, o método sonoro do
animal é chamado, então ele imprime algum som
genérico de animal polimorfismo permite que
o som do mesmo método se comporte de forma diferente
dependendo do tipo do objeto Nesse caso,
embora estejamos chamando o mesmo método de som para
todos os objetos na lista, o comportamento real que é impresso depende da classe
específica de cada objeto, cachorro, gato ou animal. Aqui temos as classes de cães e gatos que herdam
da classe animal, o que significa que eles herdam
seu método, No entanto, eles substituem
o método de som para fornecer uma
implementação específica O método de som é chamado da mesma forma em todos os objetos. Mas o método real que é executado depende do
tipo do objeto, que é determinado em tempo de execução. O método de som fornece resultados
diferentes com base no
tipo de objeto que o chama. Isso torna o código mais
flexível e reutilizável porque classes
diferentes podem usar o mesmo nome de método, mas têm
seu próprio comportamento exclusivo polimorfismo ajuda a tornar o código
Python mais
flexível, reutilizável
e fácil de manter, e fácil de manter, pois permite que o mesmo
método manipule diferentes tipos de objetos de Por enquanto, isso é tudo. Nos
vemos na próxima aula.
36. OOP em Python: encapsulamento: Bem vindos de volta, pessoal. Vamos mergulhar no conceito
de encapsulamento encapsulamento é um dos princípios
fundamentais
da programação orientada a objetos,
junto com herança, polimorfismo Em geral, o encapsulamento significa combinar dados
como variáveis e métodos, como
funções, que funcionam nesses dados em uma unidade
chamada classe, e também restringe acesso
direto a alguns dos componentes do objeto,
o que pode evitar a
modificação acidental dos Isso é obtido por meio modificadores de
acesso que controlam a visibilidade dos membros
da classe Em Python, o encapsulamento
é feito usando classes. Você pode controlar
o acesso aos dados usando
diferentes níveis de acesso, públicos, protegidos e
privados, membros públicos. Eles são acessíveis
de qualquer lugar, dentro e
fora da sala de aula. Então, protegemos os membros. Eles são indicados por um único prefixo de sublinhado
e devem ser acessados somente dentro
da classe e de
suas subclasses e suas subclasses e Eles são indicados pelo prefixo de sublinhado
duplo e não
podem ser acessados diretamente
de fora da classe Então, vamos mergulhar nesse conceito com explicações
detalhadas Por padrão, todos os
atributos e métodos dos membros na classe
Python são públicos, que significa que eles podem ser acessados
de fora da Por exemplo, aqui eu defino
uma nova classe chamada carro. Essa classe tem um método
construtor que é chamado automaticamente quando uma instância da
classe é criada Marca e modelo são parâmetros que passamos ao criar
um novo objeto de carro. Marca própria e modelo próprio são atributos públicos
da classe. Python, como eu disse antes, todos os atributos são
públicos por padrão, que significa que eles podem ser acessados e modificados de
fora da classe Os valores passados como argumentos marca e modelo são atribuídos a
esses atributos. Por exemplo, se criarmos o objeto do carro com o
carro Toyota Camry, marca própria
será Toyota e o
modelo próprio será Em seguida, crio as informações de exibição do
método. É um método público, o que significa que pode ser chamado
de fora da classe. Esse método imprime a marca e o modelo do
carro usando os atributos públicos de marca
própria e modelo próprio. Em seguida, eu crio
uma instância da classe de carros. Eu passo pela Toyota na marca e Camry no modelo ao
criar esse objeto Como sabemos, o método it
é automaticamente chamado inicializar carro de uma marca para Toyota e carro de um
modelo para E então eu
chamo o método público exibição de entrada
no carro de um objeto Esse método usa o
valor armazenado no carro uma marca e no carro de um modelo
para exibir as informações. E a principal coisa que
devemos lembrar agora é
que, como marca e modelo
são atributos públicos, podemos acessá-los diretamente
usando a notação de pontos Então, aqui, marca de carro com um ponto e modelo de
carro com um ponto,
imprima o resultado. Então, aqui temos
o exemplo em marca e modelo são atributos
públicos, e eu posso acessá-los e
modificá-los diretamente de
fora da classe usando
a instância da classe. E aqui está como eu posso fazer isso. Claro, aqui eu
posso substituir o modelo. O método exibido
em for é público, o que significa que ele pode ser
chamado de fora da classe de qualquer
instância da classe. Agora, modificamos diretamente os atributos públicos,
a marca e o modelo
do carro, um objeto porque
os atributos são públicos, eles podem ser modificados livremente de
fora da classe,
sem qualquer restrição. Então, depois disso, temos a marca
Honda e o modelo Accord. Agora, se chamarmos o método display in
for novamente no carro 1,
o método imprimirá uma mensagem
totalmente diferente. Quero dizer, teremos uma nova
marca e um novo modelo. Então, recapitulando rapidamente, membros públicos, atributos e métodos são totalmente acessíveis de
fora da classe Isso é útil para
atributos e métodos que você deseja expor
para uso geral No entanto, se você precisar proteger determinados dados de serem
acessados ou modificados diretamente, você usaria membros protegidos
ou privados. Vou comentar
o código anterior e continuar com os membros
protegidos. Então, aqui temos uma lógica totalmente
diferente. Eu
crio uma pessoa da classe , a classe da pessoa
representa uma pessoa com dois
atributos protegidos: nome e idade. O sublinhado vivo
nos nomes,
nome e idade dos atributos é uma convenção para indicar que esses
são membros protegidos Essa convenção diz a
outros desenvolvedores que esses atributos
são destinados uso
interno e não devem ser acessados
diretamente de fora
da classe ou das subclasses Aqui temos informações de exibição do método e também é um método
protegido. Ele segue a mesma convenção de
nomenclatura com um sublinhado inicial Ele imprime o nome
e a idade da pessoa adicionando os
atributos protegidos nome e idade. Em seguida, crio a classe de funcionário que herda
da classe de pessoa Isso significa que ele pode usar os atributos e métodos
da classe person. O método NIT na classe de
funcionários chama o método NIT da
classe de pessoa usando a superfunção Isso inicializa os atributos de
nome e idade. A classe de funcionário
introduz um novo atributo, ID do
funcionário, que é
específico para o funcionário O método show details na classe
do funcionário chama o
método protegido exibe informações da classe da pessoa principal. Isso é permitido porque
o método é protegido, que significa que ele pode ser acessado a partir da
subclasse employee Então, aqui estamos chamando o método protegido
da classe mãe. Mostrar detalhes imprime
as informações sobre o nome do funcionário, a
idade da classe principal e a identificação do funcionário. Em seguida, criamos uma instância
da classe de funcionários chamada P e passamos John com o nome 30 no H
e e123 no ID do funcionário O construtor da classe de funcionário
chama
o construtor de classes de pessoa usando nome da
superconfiguração
para John e ele 30,
a
ID do funcionário é definida como e13 Em seguida, chamo o método show
details on the MP object. Em show details, o método
display Info
da classe person é chamado, que imprime os nomes John e H 30. Depois disso, o
ID e123 do funcionário também é impresso. Portanto, o ponto principal nos membros protegidos em Python
são atributos ou membros que devem ser usados somente dentro da classe
e por suas Eles são indicados por um único sublinhado inicial antes do nome do atributo
ou método Membros protegidos
não são extremamente privados. convenção de nomenclatura do Python com um sublinhado principal
sinaliza para outros desenvolvedores que esses membros são destinados uso
interno e não devem ser acessados diretamente de
fora da classe No entanto, isso é
apenas uma convenção. O Python não impõe restrições de acesso
. Como você pode ver claramente
aqui, na classe person, tínhamos dois
atributos protegidos nome e idade e um
método protegido, exibir informações. Esses membros
não devem ser acessados diretamente de fora
da classe, mas podem ser
acessados se necessário, já que o Python não impõe um controle de acesso
rígido Então eu crio uma instância
da classe pessoa, pessoa um. E eu acesso o nome da pessoa com um
nome e a pessoa com um, cada um diretamente fora da classe. Embora
geralmente seja considerado má prática acessar membros
protegidos
fora da classe, ele permite isso
porque não tem mecanismo de fiscalização
rígido, como outras linguagens, como
Java ou C plus plus. Também ligo para o diretor de
informações de exibição de
fora da classe. Novamente, é permitido,
mesmo estando protegido. Então, por que devemos
seguir a convenção? Se eu seguir a
convenção e tratar os membros
protegidos como
internos à classe, isso manterá o design do
código limpo e modular. código externo não deve O código externo não deve
depender da
estrutura interna de uma classe, pois isso dificulta futuras alterações na
classe. Ao seguir essa convenção, você evita que os
detalhes internos
da classe sejam acessados
ou alterados diretamente, o que ajuda a evitar bugs. Então, recapitulação rápida. Em Python os membros
protegidos
são uma convenção, não uma regra imposta Você pode acessá-los fora
da classe ou subclasse, mas isso quebra a estrutura pretendida e pode levar a um design de software incorreto Vamos continuar com os membros
privados. Eu comento o código anterior. Eu crio a classe de
conta bancária que tem dois atributos privados: número e saldo da
conta. Membros privados em Python são prefixados com Eu também crio o equilíbrio de exibição do
método e também é um método privado. Ele só deve ser
usado dentro da classe. Os prefixos de sublinhado duplo
também se aplicam aos métodos, o que significa que esse método
não pode ser acessado de
fora da classe Em seguida, eu crio o método
de saque. É um método público. Ele pode ser acessado de
fora da classe. Esse método interage com o equilíbrio de atributos privados e chama o
método privado display balance Ele verifica se
há
fundos suficientes para a retirada. Se sim, ele deduz o
valor do saldo. Caso contrário, ele imprime fundos
insuficientes. Depois de processar a retirada, ele chama o
método privado de exibição do saldo para mostrar o saldo atualizado. Eu crio a instância
da conta bancária com o número da conta e saldo
inicial de 1.000. Quando eu chamo a conta de
saque 200, ela deduz 200
do saldo inicial de 1.000, resultando em um novo
saldo de 800 Se eu executar esse código, veremos uma mensagem mostrando que
200 foram retirados, deixando um saldo de 800 Se eu tentar acessar
o saldo da
conta ou o
saldo de exibição da conta de fora da classe, isso gerará um erro de atributo porque esses
membros são particulares e os membros privados são atributos ou métodos que devem ser ocultados do acesso
externo. O mesmo erro que
receberei se
tentar acessar o saldo de exibição do
método privado. Ao manter os atributos privados, você pode fornecer acesso
controlado por meio de métodos públicos,
como retirar, garantindo que os dados
permaneçam em um estado válido. Apesar do
fato de o Python usar atributos
privados para aplicar
o princípio do encapsulamento , que o estado interno de um objeto é O PyTN também tem um mecanismo
chamado alteração de nomes que permite acessar esses atributos privados de uma
maneira Isso significa que você ainda pode acessar os atributos privados se
souber o nome alterado, mas isso é considerado uma má prática porque viola o princípio de
encapsulamento Essa linha de código permite acessar o atributo privado
usando seu nome mutilado,
e é um sublinhado, nome da
classe, para sublinhar o nome do atributo Sim, é mais difícil, mas é possível acessar
fora da sala de aula. E esse mecanismo é
chamado de mutilação de nomes. Então, uma rápida recapitulação sobre atributos
privados. Em Python, eles
são criados usando sublinhado
duplo e
devem ser ocultados
do acesso Mas o Python usa a manipulação para alterar o nome dos atributos
privados,
tornando-os mais difíceis, mas não
impossíveis, de acessar
de fora da classe Você ainda pode acessar atributos
privados
usando o nome distorcido, mas é uma prática ruim A forma preferida de
interagir com dados
privados é por meio de métodos
públicos, que garantem a integridade dos dados
e mantêm o encapsulamento Por enquanto, isso é tudo.
Na próxima lição, abordaremos
iniciantes e definidores Nos
vemos na próxima
37. OOP em Python: getters, setters e propriedades: Bem vindos de volta, pessoal.
Vamos mergulhar na explicação
detalhada
do encapsulamento usando Getters e erros
em Já sabemos o que é
encapsulamento encapsulamento também
fornece uma maneira controlar o acesso aos dados tornando certos atributos
privados e expondo-os somente
por meio privados e expondo-os Getters e setters são métodos usados para acessar e modificar atributos
privados de uma classe Eles fornecem uma forma controlada interagir com dados privados, garantindo que os dados sejam
tratados de forma adequada e segura O objetivo de usar
Getters and setters é
proteger os dados contra acesso externo
direto
e modificações e Vamos ver como isso
funciona na prática. Eu começo com a
classe de inicialização funcionário, e essa classe tem dois atributos particulares,
nome e salário Esses atributos são prefixados
com sublinhados duplos, tornando-os privados e não diretamente acessíveis
de fora da classe É hora de usar
Getter como nome. Esse método retorna o valor do nome do atributo privado. Ao usar um Getter, você pode controlar como o
atributo é acessado Por exemplo, você pode adicionar registros ou verificações adicionais posteriormente sem alterar
o resto do código. E depois de Getter,
vamos definir setter. Esse método atualiza o valor do nome do atributo privado. Ele atribui diretamente o novo
valor sem validação, mas você pode adicionar
verificações se necessário Eu também crio o Getter por salário. Da mesma forma, esse método retorna o valor do salário do
atributo privado. E pagador de salário. Esse método inclui
validação para garantir que o salário seja positivo antes de atualizar o salário do
atributo privado. Se um valor inválido, como salário
negativo, for passado , ele imprimirá uma mensagem de erro e
não atualizará o salário Então eu crio uma
instância da classe de funcionários, defino o nome Alice
e o salário de 4.000 E agora eu posso usar o Getter. Vou usar Get name. O método recupera o
nome do funcionário. Vamos testar o salário do setter. Esse método atualiza o
salário para 6.000, e também usarei Gary Getter Esse método recupera
o salário atualizado. Então, quando executo esse código, o método get name é chamado e ele retorna o nome do atributo
privado. Como o nome foi dito a Ellis, a saída é Allie Em seguida, o
método de salário definido é chamado com 6.000 no argumento Como 6.000 é
maior que zero, o configurador atualiza o salário do atributo
privado para 6.000 e, em seguida, o método get
salary é chamado e retorna o valor atualizado do do atributo privado Como o regulador atualizou o
salário para 6.000, a produção é de Então, recapitulando rapidamente, Getters
e setters são métodos que fornecem acesso
controlado a
atributos privados Eles ajudam a obter
encapsulamento, validação de
dados e flexibilidade Use Getters para recuperar dados
privados e setters para modificá-los com
validação opcional A remoção de setters pode fazer com que
um atributo seja lido somente enquanto a remoção de getters
pode torná-lo somente nós Essa abordagem garante que
seu código seja mais limpo, mais seguro e
mais fácil de manter. Ao usar Getters e setters, você pode proteger
o estado interno
do seu objeto e garantir que integridade dos
dados seja
mantida em todo
o aplicativo .
Mas isso não é tudo. Em Python, você pode usar o decorador de
propriedades para simplificar
a criação de métodos getter
e setter para atributos privados. Isso permite que você acesse e modifique atributos privados de uma forma mais Pythônica sem chamar
explicitamente os métodos Getter e Setter O decorador de propriedades
permite definir métodos que agem
como atributos, dando a ilusão de acesso
direto aos atributos e, ao
mesmo tempo, permitindo que você defina um comportamento personalizado para obter e
definir os valores Essa abordagem é
mais concisa e limpa em comparação com o método
getter setter tradicional decorador de propriedades simples é usado para criar um método getter. Ele permite que você acesse
um atributo privado forma controlada sem
chamar um método explicitamente O decorador Setter usa uma assinatura
ligeiramente diferente. É usado para definir
um método setter. Isso permite que você modifique
um atributo privado ao mesmo tempo, adicione lógica
, como validação. Portanto, um exemplo de classe de
funcionário ligeiramente modificado para usar decoradores de propriedades
para iniciantes e Aqui, depois de criar uma
instância de funcionário, posso acessar o
atributo privado via Getter Nome. Então, posso modificar o atributo
privado via setter e definir
6.000 salários válidos Também posso acessar
o valor atualizado. Se eu tentar definir
um salário inválido, receberei a mensagem salário
inválido Quais são as vantagens de
usar decoradores de propriedades? Sintaxe mais limpa. Você pode acessar e modificar
atributos usando a mesma sintaxe dos atributos
públicos sem chamar explicitamente os métodos
Getter e Setter O estado interno do
objeto permanece protegido e você pode controlar o acesso a ele por meio de
Getters e setters,
adicionando
lógica de validação, se Você pode adicionar
ou modificar facilmente a lógica
nos métodos setter do Getter sem alterar a
interface externa da classe Usar decretores de propriedades em
Python permite que você alcance o
comportamento de Getter e Setter de uma forma mais Isso simplifica o código e essa abordagem é
mais limpa do que definir manualmente métodos
getter e setter e ajuda a manter boas Por enquanto, isso é tudo. Nos
vemos na próxima aula.
38. OOP em Python: agregação: Bem vindos de volta, pessoal. Hoje,
analisaremos a agregação. Tanto a agregação quanto a
composição são tipos de associações que
definem relacionamentos entre objetos na programação
orientada a objetos Composição que descobrimos
na lição anterior. Agora vamos continuar
com a agregação. agregação tem um relacionamento em que um objeto pode
conter outros objetos, mas esses objetos ainda
podem existir
sozinhos , separados
do contêiner Os objetos contidos podem existir mesmo se o
objeto do contêiner for destruído. Por exemplo, considere uma
universidade e seus estudantes. Se o
objeto universitário for excluído, o objeto estudantil
ainda existirá de forma independente. Vamos continuar com o exemplo. Vou criar um livro didático. Ele contém o método, é um método especial em
Python, Ele inicializa um
novo objeto de livro. Cada objeto do livro
terá um atributo de título. Então eu crio a biblioteca de classes. Ele também tem construtor. Ele cria uma
lista vazia chamada livros. Essa lista será usada
para armazenar objetos de livros. A classe library tem uma
lista de objetos de livros, mas não os possui. Os livros podem existir
independentemente da biblioteca. Em seguida, defino um método chamado at book
na classe de biblioteca. O método usa dois argumentos, self, a instância da biblioteca, e book, instância do livro. Esse método adiciona o objeto livro à lista de livros na instância
da biblioteca. Então eu criei dois objetos de livro com
títulos diferentes. Em seguida, crio um
objeto de biblioteca chamado Biblioteca. O método addBook é chamado duas vezes para adicionar o Livro um e o Livro dois à lista de livros da
biblioteca O que temos agora, temos uma
biblioteca com vários livros. Vamos adicionar os livros de
exibição do método. Esse método permite que você veja todos os livros que
foram adicionados à biblioteca. Esse método simplesmente verifica se há algum livro
na biblioteca. Se houver livros, ele exibirá seus títulos
usando quatro voltas. Self books é uma lista que
pertence ao objeto da biblioteca. Estava vazio antes de
adicionarmos dois livros. Cada item dessa lista
é um objeto de livro. A linha para livro em
livros próprios significa pegar cada item da lista de livros próprios, um por um, e atribuí-lo
à variável livro. O loop
continuará até que não
haja mais itens
na lista. No nosso exemplo,
isso acontece duas vezes e depois imprimimos
o título do livro. Aqui temos o atributo title do objeto do livro atual. Já sabemos
que podemos acessar os atributos de um
objeto usando a notação de pontos Isso significa que você pode se referir às propriedades
e métodos de
um objeto
escrevendo o
nome do objeto seguido pelo ponto e depois pelo nome do atributo. No nosso caso,
temos o objeto do livro e também temos o título como
atributo . Vamos testá-lo. Se eu executar esse código agora, obteremos a lista de livros. Vamos deletar a biblioteca. O método exclui o
objeto da biblioteca da memória. Isso significa que o
objeto da biblioteca e seus atributos, como a lista de livros
contida , não estão
mais acessíveis. Apesar de excluir a biblioteca, os
objetos Livro um e Livro dois ainda existem na memória porque foram criados independentemente
da biblioteca e podemos acessá-los Por exemplo, aqui eu
imprimo o título do livro um, e aqui temos o resultado. Vou comentar o código desnecessário
anterior porque não temos mais o objeto de
biblioteca e aqui
vemos claramente o resultado. E isso demonstra
agregação. A biblioteca tem uma
coleção de livros, mas não os possui. Os objetos do livro não são destruídos quando a
biblioteca é destruída. Ainda posso trabalhar porque o
primeiro livro existe independentemente
da biblioteca. O livro dois existe
e podemos usá-lo. A classe library
contém uma lista de objetos de
livros, livros próprios. No entanto, esses objetos do livro não
estão fortemente vinculados
à biblioteca. Eles podem existir sozinhos,
independentemente da biblioteca. Por outro lado, os objetos
do livro, Livro um e Livro dois, são independentes do objeto da
biblioteca. A exclusão do objeto de biblioteca não afeta a
existência de objetos de livro Essa estrutura de código ajuda na criação de programas modulares e
flexíveis em que componentes como
livros podem ser reutilizados independentemente do
contêiner principal, como uma biblioteca Recapitulação rápida,
agregação usada quando um objeto usa outro objeto temporariamente
e não o possui Composição usada
quando um objeto é completamente dependente de
outro para sua existência. O objeto contido não pode
existir sem o contêiner. Por exemplo, humano,
coração ou carro e motor, mas a
abordagem geral no código para composição
e
agregação é semelhante Ambos usam classes contendo
referências a outros objetos. A principal diferença é
que, na composição, o objeto contido depende inteiramente do pai e
é destruído com ele. Enquanto estão agregados, os objetos contidos podem existir independentemente
do pai Espero ter conseguido
explicar claramente a diferença. Por enquanto, isso é tudo. Nos
vemos na próxima aula.
39. OOP em Python: abstração: Bem vindos de volta, pessoal.
Agora, vamos mergulhar no conceito de abstração na programação orientada a objetos abstração é um
dos conceitos fundamentais
que ajuda a manter complexidade
do código, ocultando detalhes
desnecessários e expondo apenas os recursos essenciais entrada e a abstração
permitem que você se concentre no que um objeto faz e não em
como ele o faz É o processo de ocultar os detalhes
de implementação de um objeto ou função e mostrar somente os recursos necessários e relevantes
para o usuário. Esse é o conceito de
modelar objetos do mundo real uma forma que se concentre em seus
atributos e comportamentos essenciais, ignorando quaisquer detalhes relevantes Por exemplo, considere
um objeto de carro. Você só precisa saber
como ligar o carro. Você não precisa entender
o mecanismo interno. Na programação, a
abstração
nos ajuda a representar
esses objetos e suas interações sem
entrar na complexidade de sua implementação
subjacente Em Python, a abstração
é obtida usando classes
abstratas e
métodos abstratos Classes abstratas, são classes que não podem ser
instanciadas diretamente. Eles só podem ser usados como um
modelo para outras classes. Métodos abstratos, métodos
que são declarados, mas não contêm implementação. Qualquer subclasse herdada de uma classe abstrata deve fornecer uma implementação
para esses métodos Para implementar a
abstração e o Python , usamos o módulo de classe base
abstrata ABC
, que fornece a classe ABC
e o decorador do e Vamos ver como isso
funciona na prática. Então, na primeira etapa, eu importo a
classe base abstrata do módulo ABC e também importo o método
abstrato Então eu defino uma classe
abstrata
herdando da classe ABC Aqui eu defino o método abstrato. Vai fazer barulho. No momento, temos uma classe abstrata
semelhante a um animal e fazemos o som como um
método abstrato sem implementação. Agora vou criar
subclasses que herdam da classe abstrata e fornecem implementações para
os Eu crio a classe de cães. Aqui eu implemento o Mesund e
depois crio o gato. O gato também herda da classe
abstrata animal. Essas duas classes fornecem a implementação do método
make sound. Em seguida,
crio instâncias das subclasses, cachorro e gato, e imprimo make sound for dog instance e imprimo make
sound for cat instance Se eu executar esse código, veremos que a
saída é diferente. Tentar instanciar
a classe abstrata diretamente gerará um erro Eu não posso fazer isso. Não consigo criar uma instância
de uma classe abstrata diretamente porque ela contém um método abstrato que não
tem implementação. Tentar fazer isso
resultará em um erro de tipo , pois o Python não sabe como executar esse método
implementado Ao herdar de
uma classe abstrata, subclasse está dizendo que
fornecerei a implementação específica para todos os métodos abstratos
da classe mãe Depois que a subclasse implementa
os métodos abstratos, você pode criar uma instância
da subclasse e usar o comportamento completo definido
pela classe abstrata e
sua própria Vamos considerar isso
com outro exemplo. Eu comentei o
código anterior, então criei uma conta. É uma classe abstrata
que herda do ABC. Isso torna a conta uma classe base
abstrata. O método need inicializa uma instância com um atributo de saldo
inicial, que representa o
dinheiro na conta Esse saldo é armazenado como um
autoequilíbrio variável de instância. E então eu crio dois métodos abstratos
de depósito e retirada. Esses métodos são definidos, mas não implementados na conta da classe
abstrata. O
decorador do método abstrato garante que esses métodos
sejam implementados por qualquer
subclasse de conta não abstrata Deposite um método que
aumentará o saldo
da conta no valor determinado. Retire um método que
diminuirá o saldo
da conta no valor determinado. Até mesmo nossos fundos estão disponíveis. Como account é
uma classe abstrata, esses métodos são
apenas decorações e nenhuma funcionalidade
é fornecida Qualquer classe herdada da
conta deve implementar esses métodos para definir o comportamento real de depósito e
saque Então eu crio uma conta poupança que é uma classe concreta que
herda da conta Ele fornece
implementação específica para os métodos de depósito e
retirada. A lógica aqui é quando o depósito
é chamado com um valor, o saldo da conta
é aumentado nesse valor
e, em seguida, imprimimos
o saldo atualizado. O método de saque
verifica se o valor a ser retirado é menor ou
igual ao saldo atual Se houver fundos suficientes, o valor será subtraído do saldo e
o saldo atualizado será
impresso Se não houver fundos suficientes, a mensagem será impressa
para indicar isso. Essa implementação da conta
poupança garante que os usuários não possam sacar
mais do que o saldo disponível, aplicando a regra
para contas de poupança A conta corrente é outra subclasse
concreta de conta, mas implementa os métodos de
depósito e saque forma diferente da conta poupança O método de depósito funciona da
mesma forma que na conta poupança, adicionando valor ao saldo e imprimindo o novo saldo. Nesse caso, o método de
saque não verifica se há fundos
suficientes. Em vez disso, permite o cheque especial, o
que significa que o saldo
pode ficar negativo Quando o valor é retirado, ele é simplesmente subtraído
do saldo,
mesmo que o
saldo fique negativo Esse comportamento representa uma conta corrente
típica em que o cheque especial é permitido, e o banco pode
fornecer um limite de crédito ou cobrar taxas por
essas transações A conta de classe abstrata
impõe que qualquer subclasse, como conta poupança
ou conta corrente, deve implementar os métodos de depósito
e saque Dessa forma, todos os tipos de conta
têm uma interface consistente, permitindo que você os manipule
da mesma forma em seu código. Assim, você pode depositar ou sacar
de qualquer tipo de conta. A classe abstrata fornece
uma interface comum, enquanto as subclasses
implementam a lógica específica A estrutura facilita a manutenção e a extensão do código . Por exemplo, se
você quiser adicionar outro tipo de conta,
como conta comercial, poderá
fazer isso facilmente criando uma nova subclasse que implemente
os métodos necessários Um objeto de conta poupança começa
com o saldo de 1.000. Você pode depositar e sacar, mas os saques podem
exceder o saldo Aqui tínhamos 1.000,
depois depositamos 500. E então eu tento retirar 2000. E se eu executar esse código, veremos a mensagem fundos
suficientes. Enquanto um objeto de conta corrente também
começa com 1.000. Mas permite saques a descoberto. Assim, você pode sacar
mais do que o saldo, resultando em um saldo negativo. E se eu executar esse código, receberei um erro porque,
desculpe o erro de ortografia,
isso é muito Agora funciona. Esse
código mostra como classes
abstratas podem
ser usadas para criar um modelo geral para
diferentes tipos de contas. Ele permite flexibilidade
ao permitir que as subclasses personalizem métodos específicos,
como depósito e saque Essa abordagem usa
polimorfismo e garante que todas as subclasses
implementem os métodos necessários, tornando esse código mais confiável
e Então, recapitulação rápida. A abstração é um conceito central na programação
orientada a objetos que se
concentra em atingir detalhes complexos de
implementação e mostrar apenas os
recursos essenciais ao usuário Ele permite que você defina
um plano para uma classe, especificando o que
os métodos devem fazer, mas não como eles devem fazer isso Em Python, a abstração
é obtida usando classes
abstratas e
métodos abstratos Uma classe abstrata é uma classe que não pode ser
instanciada sozinha E é usado apenas como
base para outras classes. Um método abstrato é um método então declarado como classe abstrata
sem qualquer implementação. As subclasses devem fornecer sua própria implementação
desses métodos abstração ajuda a reduzir complexidade simplificando
a instrução com objetos e forçando uma interface
consistente para subclasses e incentivando a reutilização e a modularidade
do código,
facilitando a manutenção e a extensão do código Parabéns por
concluir esta seção sobre programação orientada a objetos. Vamos passar para outros tópicos.