Programação em Python: do iniciante ao domínio de OOP | Olha Al | Skillshare
Pesquisar

Velocidade de reprodução


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Programação em Python: do iniciante ao domínio de OOP

teacher avatar Olha Al

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Aulas neste curso

    • 1.

      Apresentação

      1:55

    • 2.

      Instalação do Python

      6:04

    • 3.

      Configuração: instalação de editores de código

      3:54

    • 4.

      Como gerenciar versões do Python: ambientes virtuais e Pyenv

      11:55

    • 5.

      Explicação da sintaxe Python e diretrizes do PEP

      6:41

    • 6.

      Tipos de dados numéricos em Python: int, float e complexo

      6:39

    • 7.

      Tipos de dados primitivos e de referência em Python

      4:59

    • 8.

      Trabalhando com strings em Python

      10:30

    • 9.

      Como entender o tipo de dados Lista em Python

      8:47

    • 10.

      Explorando o tipo de dados tupla em Python

      9:09

    • 11.

      Como entender o tipo de dados booleano em Python

      4:54

    • 12.

      Trabalhando com o tipo de dados do dicionário em Python

      7:22

    • 13.

      Explorando os tipos de dados Conjunto e Congelado em Python

      8:15

    • 14.

      Trabalhando com tipos de sequência binária em Python

      14:08

    • 15.

      Trabalhando com loops e condições em Python

      8:01

    • 16.

      Fluxo de controle em Python: instruções quebrar e continuar

      7:17

    • 17.

      Trabalhando com loops aninhados e declarações condicionais em Python

      8:24

    • 18.

      Usando loops com estruturas de dados aninhadas em Python

      9:30

    • 19.

      Como entender as listas em Python

      13:55

    • 20.

      Usando a função input() em Python

      7:03

    • 21.

      Introdução a funções: como criar funções em Python

      10:08

    • 22.

      Argumentos posicionais e de palavra-chave em funções Python explicadas

      8:36

    • 23.

      Usando a embalagem e desembalagem de argumentos em funções Python

      8:34

    • 24.

      Como entender as funções Lambda em Python

      7:14

    • 25.

      Entendendo o escopo em Python

      8:24

    • 26.

      Manipulando erros com try-except nas funções Python

      10:00

    • 27.

      Introdução aos módulos em Python: como trabalhar com eles e usar a declaração de importação

      16:48

    • 28.

      Usando decoradores como padrões de design em Python: como implementá-los e aplicá-los

      6:19

    • 29.

      Criando um gerador de códigos QR para redes sociais com Python

      7:19

    • 30.

      Introdução à programação orientada a objetos (OOP) em Python: cursos e objetos

      11:02

    • 31.

      OOP em Python: trabalhando com métodos de classe, estáticos e instância

      9:06

    • 32.

      OOP em Python: herança única e múltipla explicadas

      10:07

    • 33.

      OOP em Python: herança multinível e hierárquica

      7:25

    • 34.

      OOP em Python: composição

      11:46

    • 35.

      OOP em Python: polimorfismo

      5:10

    • 36.

      OOP em Python: encapsulamento

      13:32

    • 37.

      OOP em Python: getters, setters e propriedades

      6:33

    • 38.

      OOP em Python: agregação

      6:25

    • 39.

      OOP em Python: abstração

      10:39

  • --
  • Nível iniciante
  • Nível intermediário
  • Nível avançado
  • Todos os níveis

Gerado pela comunidade

O nível é determinado pela opinião da maioria dos estudantes que avaliaram este curso. Mostramos a recomendação do professor até que sejam coletadas as respostas de pelo menos 5 estudantes.

5

Estudantes

--

Projeto

Sobre este curso

Este curso de programação em Python foi projetado para iniciantes e abrange conceitos essenciais como a programação orientada a objetos (OOP), funções e estruturas de dados. Neste curso, vamos criar um aplicativo gerador de código QR para seus perfis de mídia social, trabalhar com módulos Python e mergulhar nas estruturas de dados essenciais. Ao final, você vai ter experiência prática e um projeto prático para mostrar suas habilidades.
Neste curso, você vai encontrar uma enorme coleção de tarefas práticas de casa para ajudar a reforçar o material.

Conheça seu professor

Teacher Profile Image

Olha Al

Professor
Level: Beginner

Nota do curso

As expectativas foram atingidas?
    Superou!
  • 0%
  • Sim
  • 0%
  • Um pouco
  • 0%
  • Não
  • 0%

Por que fazer parte da Skillshare?

Faça cursos premiados Skillshare Original

Cada curso possui aulas curtas e projetos práticos

Sua assinatura apoia os professores da Skillshare

Aprenda em qualquer lugar

Faça cursos em qualquer lugar com o aplicativo da Skillshare. Assista no avião, no metrô ou em qualquer lugar que funcione melhor para você, por streaming ou download.

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.