"message": "As this PR has been waiting for the original user for a while but seems to be inactive, it's now going to be closed. But if there's anyone interested, feel free to create a new PR."
},
"invalid": {
"delay": 0,
"message": "This was marked as invalid and will be closed now. If this is an error, please provide additional details."
* 🌐 Add Traditional Chinese translation for `docs/zh-hant/docs/deployment/cloud.md`. PR [#12440](https://github.com/fastapi/fastapi/pull/12440) by [@codingjenny](https://github.com/codingjenny).
* 🌐 Update Portuguese translation for `docs/pt/docs/python-types.md`. PR [#12428](https://github.com/fastapi/fastapi/pull/12428) by [@ceb10n](https://github.com/ceb10n).
* 🌐 Add Russian translation for `docs/ru/docs/environment-variables.md`. PR [#12436](https://github.com/fastapi/fastapi/pull/12436) by [@wisderfin](https://github.com/wisderfin).
* 🌐 Add Traditional Chinese translation for `docs/zh-hant/docs/resources/index.md`. PR [#12443](https://github.com/fastapi/fastapi/pull/12443) by [@codingjenny](https://github.com/codingjenny).
* 🌐 Add Traditional Chinese translation for `docs/zh-hant/docs/about/index.md`. PR [#12438](https://github.com/fastapi/fastapi/pull/12438) by [@codingjenny](https://github.com/codingjenny).
* 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/query-param-models.md`. PR [#12414](https://github.com/fastapi/fastapi/pull/12414) by [@ceb10n](https://github.com/ceb10n).
* 🌐 Remove Portuguese translation for `docs/pt/docs/deployment.md`. PR [#12427](https://github.com/fastapi/fastapi/pull/12427) by [@ceb10n](https://github.com/ceb10n).
* 🌐 Add Portuguese translation for `docs/pt/docs/tutorial/body-updates.md`. PR [#12381](https://github.com/fastapi/fastapi/pull/12381) by [@andersonrocha0](https://github.com/andersonrocha0).
* 🌐 Add Portuguese translation for `docs/pt/docs/advanced/response-cookies.md`. PR [#12417](https://github.com/fastapi/fastapi/pull/12417) by [@Paulofalcao2002](https://github.com/Paulofalcao2002).
* 🔧 Update team, include YuriiMotov 🚀. PR [#12453](https://github.com/fastapi/fastapi/pull/12453) by [@tiangolo](https://github.com/tiangolo).
* 👷 Refactor label-approved, make it an internal script instead of an external GitHub Action. PR [#12280](https://github.com/fastapi/fastapi/pull/12280) by [@tiangolo](https://github.com/tiangolo).
* 👷 Fix smokeshow, checkout files on CI. PR [#12434](https://github.com/fastapi/fastapi/pull/12434) by [@tiangolo](https://github.com/tiangolo).
**Python 3.6 +** tem suporte para "type hints" opcionais.
O Python possui suporte para "dicas de tipo" ou "type hints" (também chamado de "anotações de tipo" ou "type annotations")
Esses **"type hints"** são uma nova sintaxe (desde Python 3.6+) que permite declarar o <abbrtitle ="por exemplo: str, int, float, bool">tipo</abbr> de uma variável.
Esses **"type hints"** são uma sintaxe especial que permite declarar o <abbrtitle ="por exemplo: str, int, float, bool">tipo</abbr> de uma variável.
Ao declarar tipos para suas variáveis, editores e ferramentas podem oferecer um melhor suporte.
Este é apenas um **tutorial rápido / atualização** sobre type hints Python. Ele cobre apenas o mínimo necessário para usá-los com o **FastAPI**... que é realmente muito pouco.
Este é apenas um **tutorial rápido / atualização** sobre type hints do Python. Ele cobre apenas o mínimo necessário para usá-los com o **FastAPI**... que é realmente muito pouco.
O **FastAPI** é baseado nesses type hints, eles oferecem muitas vantagens e benefícios.
Mas mesmo que você nunca use o **FastAPI**, você se beneficiaria de aprender um pouco sobre eles.
/// note | "Nota"
/// note | Nota
Se você é um especialista em Python e já sabe tudo sobre type hints, pule para o próximo capítulo.
@ -35,8 +35,8 @@ John Doe
A função faz o seguinte:
* Pega um `first_name` e `last_name`.
* Converte a primeira letra de cada uma em maiúsculas com `title()`.
* <abbrtitle ="Agrupa-os, como um. Com o conteúdo de um após o outro.">Concatena</abbr> com um espaço no meio.
* Converte a primeira letra de cada uma em maiúsculas com `title()`.
* <abbrtitle ="Agrupa-os, como um. Com o conteúdo de um após o outro.">Concatena</abbr> com um espaço no meio.
```Python hl_lines="2"
{!../../docs_src/python_types/tutorial001.py!}
@ -48,7 +48,7 @@ A função faz o seguinte:
Mas agora imagine que você estava escrevendo do zero.
Em algum momento você teria iniciado a definição da função, já tinha os parâmetros prontos...
Em algum momento você teria iniciado a definição da função, já tinha os parâmetros prontos...
Mas então você deve chamar "esse método que converte a primeira letra em maiúscula".
@ -96,37 +96,37 @@ Isso não é o mesmo que declarar valores padrão como seria com:
Estamos usando dois pontos (`:`), não é igual a (`=`).
E adicionar type hints normalmente não muda o que acontece do que aconteceria sem elas.
E adicionar type hints normalmente não muda o que acontece do que aconteceria sem eles.
Mas agora, imagine que você está novamente no meio da criação dessa função, mas com type hints.
No mesmo ponto, você tenta acionar o preenchimento automático com o `CtrlSpace` e vê:
No mesmo ponto, você tenta acionar o preenchimento automático com o `Ctrl+Space` e vê:
<imgsrc="/img/python-types/image02.png">
Com isso, você pode rolar, vendo as opções, até encontrar o que "toca uma campainha":
Com isso, você pode rolar, vendo as opções, até encontrar o que "soa familiar":
<imgsrc="/img/python-types/image03.png">
## Mais motivação
Marque esta função, ela já possui type hints:
Verifique esta função, ela já possui type hints:
```Python hl_lines="1"
{!../../docs_src/python_types/tutorial003.py!}
```
Como o editor conhece os tipos de variáveis, você não apenas obtém a conclusão, mas também as verificações de erro:
Como o editor conhece os tipos de variáveis, você não obtém apenas o preenchimento automático, mas também as verificações de erro:
<imgsrc="/img/python-types/image04.png">
Agora você sabe que precisa corrigí-lo, converta `age` em uma string com `str(age)`:
Agora você sabe que precisa corrigí-lo, converta `age` em uma string com `str(age)`:
```Python hl_lines="2"
{!../../docs_src/python_types/tutorial004.py!}
```
## Tipos de declaração
## Declarando Tipos
Você acabou de ver o local principal para declarar type hints. Como parâmetros de função.
@ -151,39 +151,77 @@ Você pode usar, por exemplo:
Existem algumas estruturas de dados que podem conter outros valores, como `dict`, `list`, `set` e `tuple`. E os valores internos também podem ter seu próprio tipo.
Para declarar esses tipos e os tipos internos, você pode usar o módulo Python padrão `typing`.
Estes tipos que possuem tipos internos são chamados de tipos "**genéricos**". E é possível declará-los mesmo com os seus tipos internos.
Ele existe especificamente para suportar esses type hints.
Para declarar esses tipos e os tipos internos, você pode usar o módulo Python padrão `typing`. Ele existe especificamente para suportar esses type hints.
#### `List`
#### Versões mais recentes do Python
Por exemplo, vamos definir uma variável para ser uma `lista` de `str`.
A sintaxe utilizando `typing` é **compatível** com todas as versões, desde o Python 3.6 até as últimas, incluindo o Python 3.9, 3.10, etc.
Em `typing`, importe `List` (com um `L` maiúsculo):
Conforme o Python evolui, **novas versões** chegam com suporte melhorado para esses type annotations, e em muitos casos, você não precisará nem importar e utilizar o módulo `typing` para declarar os type annotations.
Se você pode escolher uma versão mais recente do Python para o seu projeto, você poderá aproveitar isso ao seu favor.
Em todos os documentos existem exemplos compatíveis com cada versão do Python (quando existem diferenças).
Por exemplo, "**Python 3.6+**" significa que é compatível com o Python 3.6 ou superior (incluindo o 3.7, 3.8, 3.9, 3.10, etc). E "**Python 3.9+**" significa que é compatível com o Python 3.9 ou mais recente (incluindo o 3.10, etc).
Se você pode utilizar a **versão mais recente do Python**, utilize os exemplos para as últimas versões. Eles terão as **melhores e mais simples sintaxes**, como por exemplo, "**Python 3.10+**".
#### List
Por exemplo, vamos definir uma variável para ser uma `list` de `str`.
//// tab | Python 3.9+
Declare uma variável com a mesma sintaxe com dois pontos (`:`)
Como tipo, coloque `list`.
Como a lista é o tipo que contém algum tipo interno, você coloca o tipo dentro de colchetes:
* As chaves deste `dict` são do tipo `str` (digamos, o nome de cada item).
* Os valores deste `dict` são do tipo `float` (digamos, o preço de cada item).
#### `Opcional`
#### Union
Você também pode usar o `Opcional` para declarar que uma variável tem um tipo, como `str`, mas que é "opcional", o que significa que também pode ser `None`:
Você pode declarar que uma variável pode ser de qualquer um dentre **diversos tipos**. Por exemplo, um `int` ou um `str`.
No Python 3.6 e superior (incluindo o Python 3.10), você pode utilizar o tipo `Union` de `typing`, e colocar dentro dos colchetes os possíveis tipos aceitáveis.
No Python 3.10 também existe uma **nova sintaxe** onde você pode colocar os possívels tipos separados por uma <abbrtitle='também chamado de "bitwise ou operador", mas o significado é irrelevante aqui'>barra vertical (`|`)</abbr>.
Em ambos os casos, isso significa que `item` poderia ser um `int` ou um `str`.
#### Possívelmente `None`
Você pode declarar que um valor pode ter um tipo, como `str`, mas que ele também pode ser `None`.
No Python 3.6 e superior (incluindo o Python 3.10) você pode declará-lo importando e utilizando `Optional` do módulo `typing`.
```Python hl_lines="1 4"
{!../../docs_src/python_types/tutorial009.py!}
```
O uso de `Opcional [str]` em vez de apenas `str` permitirá que o editor o ajude a detectar erros, onde você pode estar assumindo que um valor é sempre um `str`, quando na verdade também pode ser `None`.
O uso de `Optional[str]` em vez de apenas `str` permitirá que o editor o ajude a detectar erros, onde você pode estar assumindo que um valor é sempre um `str`, quando na verdade também pode ser `None`.
`Optional[Something]` é na verdade um atalho para `Union[Something, None]`, eles são equivalentes.
Isso também significa que no Python 3.10, você pode utilizar `Something | None`:
Se você está utilizando uma versão do Python abaixo da 3.10, aqui vai uma dica do meu ponto de vista bem **subjetivo**:
* 🚨 Evite utilizar `Optional[SomeType]`
* No lugar, ✨ **use `Union[SomeType, None]`** ✨.
Ambos são equivalentes, e no final das contas, eles são o mesmo. Mas eu recomendaria o `Union` ao invés de `Optional` porque a palavra **Optional** parece implicar que o valor é opcional, quando na verdade significa "isso pode ser `None`", mesmo que ele não seja opcional e ainda seja obrigatório.
Eu penso que `Union[SomeType, None]` é mais explícito sobre o que ele significa.
Isso é apenas sobre palavras e nomes. Mas estas palavras podem afetar como os seus colegas de trabalho pensam sobre o código.
Por exemplo, vamos pegar esta função:
```Python hl_lines="1 4"
{!../../docs_src/python_types/tutorial009c.py!}
```
O paâmetro `name` é definido como `Optional[str]`, mas ele **não é opcional**, você não pode chamar a função sem o parâmetro:
```Python
say_hi() # Oh, no, this throws an error! 😱
```
O parâmetro `name`**ainda é obrigatório** (não *opicional*) porque ele não possui um valor padrão. Mesmo assim, `name` aceita `None` como valor:
```Python
say_hi(name=None) # This works, None is valid 🎉
```
A boa notícia é, quando você estiver no Python 3.10 você não precisará se preocupar mais com isso, pois você poderá simplesmente utilizar o `|` para definir uniões de tipos:
E então você não precisará mais se preocupar com nomes como `Optional` e `Union`. 😎
#### Tipos genéricos
Esses tipos que usam parâmetros de tipo entre colchetes, como:
Esses tipos que usam parâmetros de tipo entre colchetes são chamados **tipos genéricos** ou **genéricos**. Por exemplo:
//// tab | Python 3.10+
Você pode utilizar os mesmos tipos internos como genéricos (com colchetes e tipos dentro):
* `list`
* `tuple`
* `set`
* `dict`
E o mesmo como no Python 3.8, do módulo `typing`:
* `Union`
* `Optional` (o mesmo que com o 3.8)
* ...entro outros.
No Python 3.10, como uma alternativa para a utilização dos genéricos `Union` e `Optional`, você pode usar a <abbrtitle='também chamado de "bitwise ou operador", mas o significado não é relevante aqui'>barra vertical (`|`)</abbr> para declarar uniões de tipos. Isso é muito melhor e mais simples.
////
//// tab | Python 3.9+
Você pode utilizar os mesmos tipos internos como genéricos (com colchetes e tipos dentro):
* `list`
* `tuple`
* `set`
* `dict`
E o mesmo como no Python 3.8, do módulo `typing`:
* `Union`
* `Optional`
* ...entro outros.
////
//// tab | Python 3.8+
* `List`
* `Tuple`
* `Set`
* `Dict`
* `Opcional`
* ...e outros.
* `Union`
* `Optional`
* ...entro outros.
são chamados **tipos genéricos** ou **genéricos**.
////
### Classes como tipos
@ -255,7 +452,7 @@ Você também pode declarar uma classe como o tipo de uma variável.
Digamos que você tenha uma classe `Person`, com um nome:
```Python hl_lines="1 2 3"
```Python hl_lines="1-3"
{!../../docs_src/python_types/tutorial010.py!}
```
@ -269,9 +466,13 @@ E então, novamente, você recebe todo o suporte do editor:
<imgsrc="/img/python-types/image06.png">
Perceba que isso significa que "`one_person` é uma **instância** da classe `Person`".
Isso não significa que "`one_person` é a **classe** chamada `Person`".
## Modelos Pydantic
<ahref="https://docs.pydantic.dev/"class="external-link"target="_blank"> Pydantic </a> é uma biblioteca Python para executar a validação de dados.
O <ahref="https://docs.pydantic.dev/"class="external-link"target="_blank">Pydantic</a> é uma biblioteca Python para executar a validação de dados.
Você declara a "forma" dos dados como classes com atributos.
@ -283,21 +484,93 @@ E você recebe todo o suporte do editor com esse objeto resultante.
Para saber mais sobre o <ahref="https://docs.pydantic.dev/"class="external-link"target="_blank"> Pydantic, verifique seus documentos </a>.
////
//// tab | Python 3.8+
```Python
{!> ../../docs_src/python_types/tutorial011.py!}
```
////
/// info | Informação
Para saber mais sobre o <ahref="https://docs.pydantic.dev/"class="external-link"target="_blank">Pydantic, verifique a sua documentação</a>.
///
**FastAPI** é todo baseado em Pydantic.
O **FastAPI** é todo baseado em Pydantic.
Você verá muito mais disso na prática no [Tutorial - Guia do usuário](tutorial/index.md){.internal-link target=_blank}.
## Type hints em **FastAPI**
/// tip | Dica
O Pydantic tem um comportamento especial quando você usa `Optional` ou `Union[Something, None]` sem um valor padrão. Você pode ler mais sobre isso na documentação do Pydantic sobre <ahref="https://docs.pydantic.dev/2.3/usage/models/#required-fields"class="external-link"target="_blank">campos Opcionais Obrigatórios</a>.
///
## Type Hints com Metadados de Anotações
O Python possui uma funcionalidade que nos permite incluir **<abbrtitle="Informação sobre a informação, neste caso, informação sobre o tipo, e.g. uma descrição.">metadados</abbr> adicionais** nos type hints utilizando `Annotated`.
//// tab | Python 3.9+
No Python 3.9, `Annotated` é parte da biblioteca padrão, então você pode importá-lo de `typing`.
Em versões abaixo do Python 3.9, você importa `Annotated` de `typing_extensions`.
Ele já estará instalado com o **FastAPI**.
```Python hl_lines="1 4"
{!> ../../docs_src/python_types/tutorial013.py!}
```
////
O Python em si não faz nada com este `Annotated`. E para editores e outras ferramentas, o tipo ainda é `str`.
Mas você pode utilizar este espaço dentro do `Annotated` para fornecer ao **FastAPI** metadata adicional sobre como você deseja que a sua aplicação se comporte.
O importante aqui de se lembrar é que **o primeiro *type parameter*** que você informar ao `Annotated` é o **tipo de fato**. O resto é apenas metadado para outras ferramentas.
Por hora, você precisa apenas saber que o `Annotated` existe, e que ele é Python padrão. 😎
Mais tarde você verá o quão **poderoso** ele pode ser.
/// tip | Dica
O fato de que isso é **Python padrão** significa que você ainda obtém a **melhor experiência de desenvolvedor possível** no seu editor, com as ferramentas que você utiliza para analisar e refatorar o seu código, etc. ✨
E também que o seu código será muito compatível com diversas outras ferramentas e bibliotecas Python. 🚀
///
## Type hints no **FastAPI**
O **FastAPI** aproveita esses type hints para fazer várias coisas.
@ -306,20 +579,20 @@ Com o **FastAPI**, você declara parâmetros com type hints e obtém:
* **Suporte ao editor**.
* **Verificações de tipo**.
... e **FastAPI** usa as mesmas declarações para:
... e o **FastAPI** usa as mesmas declarações para:
* **Definir requisitos**: dos parâmetros do caminho da solicitação, parâmetros da consulta, cabeçalhos, corpos, dependências, etc.
* **Definir requisitos**: dos parâmetros de rota, parâmetros da consulta, cabeçalhos, corpos, dependências, etc.
* **Converter dados**: da solicitação para o tipo necessário.
* **Validar dados**: provenientes de cada solicitação:
* A geração de **erros automáticos** retornou ao cliente quando os dados são inválidos.
* **Documente** a API usando OpenAPI:
* Gerando **erros automáticos** retornados ao cliente quando os dados são inválidos.
* **Documentar** a API usando OpenAPI:
* que é usado pelas interfaces de usuário da documentação interativa automática.
Tudo isso pode parecer abstrato. Não se preocupe. Você verá tudo isso em ação no [Tutorial - Guia do usuário](tutorial/index.md){.internal-link target=_blank}.
O importante é que, usando tipos padrão de Python, em um único local (em vez de adicionar mais classes, decoradores, etc.), o **FastAPI** fará muito trabalho para você.
/// info | "Informação"
/// info | Informação
Se você já passou por todo o tutorial e voltou para ver mais sobre os tipos, um bom recurso é <ahref ="https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html"class ="external-link "target =" _ blank "> a "cheat sheet" do `mypy`</a>.
Se você possui um grupo de **parâmetros de consultas** que são relacionados, você pode criar um **modelo Pydantic** para declará-los.
Isso permitiria que você **reutilizasse o modelo** em **diversos lugares**, e também declarasse validações e metadados de todos os parâmetros de uma única vez. 😎
/// note | Nota
Isso é suportado desde o FastAPI versão `0.115.0`. 🤓
///
## Parâmetros de Consulta com um Modelo Pydantic
Declare os **parâmetros de consulta** que você precisa em um **modelo Pydantic**, e então declare o parâmetro como `Query`:
O **FastAPI****extrairá** os dados para **cada campo** dos **parâmetros de consulta** presentes na requisição, e fornecerá o modelo Pydantic que você definiu.
## Verifique os Documentos
Você pode ver os parâmetros de consulta nos documentos de IU em `/docs`:
Caso um cliente tente enviar alguns dados **extras** nos **parâmetros de consulta**, eles receberão um retorno de **erro**.
Por exemplo, se o cliente tentar enviar um parâmetro de consulta `tool` com o valor `plumbus`, como:
```http
https://example.com/items/?limit=10&tool=plumbus
```
Eles receberão um retorno de **erro** informando-os que o parâmentro de consulta `tool` não é permitido:
```json
{
"detail": [
{
"type": "extra_forbidden",
"loc": ["query", "tool"],
"msg": "Extra inputs are not permitted",
"input": "plumbus"
}
]
}
```
## Resumo
Você pode utilizar **modelos Pydantic** para declarar **parâmetros de consulta** no **FastAPI**. 😎
/// tip | Dica
Alerta de spoiler: você também pode utilizar modelos Pydantic para declarar cookies e cabeçalhos, mas você irá ler sobre isso mais a frente no tutorial. 🤫
Если вы уже знаете, что такое «переменные окружения» и как их использовать, можете пропустить это.
///
Переменная окружения (также известная как «**env var**») - это переменная, которая живет **вне** кода Python, в **операционной системе**, и может быть прочитана вашим кодом Python (или другими программами).
Переменные окружения могут быть полезны для работы с **настройками** приложений, как часть **установки** Python и т.д.
## Создание и использование переменных окружения
Можно **создавать** и использовать переменные окружения в **оболочке (терминале)**, не прибегая к помощи Python:
//// tab | Linux, macOS, Windows Bash
<divclass="termy">
```console
// Вы можете создать переменную окружения MY_NAME с помощью
$ export MY_NAME="Wade Wilson"
// Затем её можно использовать в других программах, например
$ echo "Hello $MY_NAME"
Hello Wade Wilson
```
</div>
////
//// tab | Windows PowerShell
<divclass="termy">
```console
// Создайте переменную окружения MY_NAME
$ $Env:MY_NAME = "Wade Wilson"
// Используйте её с другими программами, например
$ echo "Hello $Env:MY_NAME"
Hello Wade Wilson
```
</div>
////
## Чтение переменных окружения в python
Так же существует возможность создания переменных окружения **вне** Python, в терминале (или любым другим способом), а затем **чтения их в Python**.
Например, у вас есть файл `main.py`:
```Python hl_lines="3"
import os
name = os.getenv("MY_NAME", "World")
print(f"Hello {name} from Python")
```
/// tip
Второй аргумент <ahref=«https://docs.python.org/3.8/library/os.html#os.getenv»class=«external-link»target=«_blank»>`os.getenv()`</a> - это возвращаемое по умолчанию значение.
Если значение не указано, то по умолчанию оно равно `None`. В данном случае мы указываем `«World»` в качестве значения по умолчанию.
///
Затем можно запустить эту программу на Python:
//// tab | Linux, macOS, Windows Bash
<divclass="termy">
```console
// Здесь мы еще не устанавливаем переменную окружения
$ python main.py
// Поскольку мы не задали переменную окружения, мы получим значение по умолчанию
Hello World from Python
// Но если мы сначала создадим переменную окружения
$ export MY_NAME="Wade Wilson"
// А затем снова запустим программу
$ python main.py
// Теперь она прочитает переменную окружения
Hello Wade Wilson from Python
```
</div>
////
//// tab | Windows PowerShell
<divclass="termy">
```console
// Здесь мы еще не устанавливаем переменную окружения
$ python main.py
// Поскольку мы не задали переменную окружения, мы получим значение по умолчанию
Hello World from Python
// Но если мы сначала создадим переменную окружения
$ $Env:MY_NAME = "Wade Wilson"
// А затем снова запустим программу
$ python main.py
// Теперь она может прочитать переменную окружения
Hello Wade Wilson from Python
```
</div>
////
Поскольку переменные окружения могут быть установлены вне кода, но могут быть прочитаны кодом, и их не нужно хранить (фиксировать в `git`) вместе с остальными файлами, их принято использовать для конфигураций или **настроек**.
Вы также можете создать переменную окружения только для **конкретного вызова программы**, которая будет доступна только для этой программы и только на время ее выполнения.
Для этого создайте её непосредственно перед самой программой, в той же строке:
<divclass="termy">
```console
// Создайте переменную окружения MY_NAME в строке для этого вызова программы
$ MY_NAME="Wade Wilson" python main.py
// Теперь она может прочитать переменную окружения
Hello Wade Wilson from Python
// После этого переменная окружения больше не существует
$ python main.py
Hello World from Python
```
</div>
/// tip
Подробнее об этом можно прочитать на сайте <ahref="https://12factor.net/config"class="external-link"target="_blank">The Twelve-Factor App: Config</a>.
///
## Типизация и Валидация
Эти переменные окружения могут работать только с **текстовыми строками**, поскольку они являются внешними по отношению к Python и должны быть совместимы с другими программами и остальной системой (и даже с различными операционными системами, такими как Linux, Windows, macOS).
Это означает, что **любое значение**, считанное в Python из переменной окружения, **будет `str`**, и любое преобразование к другому типу или любая проверка должны быть выполнены в коде.
Подробнее об использовании переменных окружения для работы с **настройками приложения** вы узнаете в [Расширенное руководство пользователя - Настройки и переменные среды](./advanced/settings.md){.internal-link target=_blank}.
## Переменная окружения `PATH`
Существует **специальная** переменная окружения **`PATH`**, которая используется операционными системами (Linux, macOS, Windows) для поиска программ для запуска.
Значение переменной `PATH` - это длинная строка, состоящая из каталогов, разделенных двоеточием `:` в Linux и macOS, и точкой с запятой `;` в Windows.
Например, переменная окружения `PATH` может выглядеть следующим образом:
//// tab | Linux, macOS
```plaintext
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
```
Это означает, что система должна искать программы в каталогах:
Это означает, что система должна искать программы в каталогах:
* `C:\Program Files\Python312\Scripts`
* `C:\Program Files\Python312`
* `C:\Windows\System32`
////
Когда вы вводите **команду** в терминале, операционная система **ищет** программу в **каждой из тех директорий**, которые перечислены в переменной окружения `PATH`.
Например, когда вы вводите `python` в терминале, операционная система ищет программу под названием `python` в **первой директории** в этом списке.
Если она ее находит, то **использует ее**. В противном случае она продолжает искать в **других каталогах**.
### Установка Python и обновление `PATH`
При установке Python вас могут спросить, нужно ли обновить переменную окружения `PATH`.
//// tab | Linux, macOS
Допустим, вы устанавливаете Python, и он оказывается в каталоге `/opt/custompython/bin`.
Если вы скажете «да», чтобы обновить переменную окружения `PATH`, то программа установки добавит `/opt/custompython/bin` в переменную окружения `PATH`.
Таким образом, когда вы набираете `python` в терминале, система найдет программу Python в `C:\opt\custompython\bin` (последний каталог) и использует ее.
////
Итак, если вы напечатаете:
<divclass="termy">
```console
$ python
```
</div>
//// tab | Linux, macOS
Система **найдет** программу `python` в `/opt/custompython/bin` и запустит ее.
Это примерно эквивалентно набору текста:
<divclass="termy">
```console
$ /opt/custompython/bin/python
```
</div>
////
//// tab | Windows
Система **найдет** программу `python` в каталоге `C:\opt\custompython\bin\python` и запустит ее.
Это примерно эквивалентно набору текста:
<divclass="termy">
```console
$ C:\opt\custompython\bin\python
```
</div>
////
Эта информация будет полезна при изучении [Виртуальных окружений](virtual-environments.md){.internal-link target=_blank}.
## Вывод
Благодаря этому вы должны иметь базовое представление о том, что такое **переменные окружения** и как использовать их в Python.
Подробнее о них вы также можете прочитать в <ahref="https://en.wikipedia.org/wiki/Environment_variable"class="external-link"target="_blank">статье о переменных окружения на википедии</a>.
Во многих случаях не всегда очевидно, как переменные окружения могут быть полезны и применимы. Но они постоянно появляются в различных сценариях разработки, поэтому знать о них полезно.
Например, эта информация понадобится вам в следующем разделе, посвященном [Виртуальным окружениям](virtual-environments.md).