O operador ** em Python é contextual ou depende do que é usado; quando usado com números (normalmente entre dois números), serve como um operador de exponenciação. No entanto, neste artigo veremos outro contexto em que é usado. Veremos seu uso como um operador de descompactação, usado para descompactar dicionários Python.
Qualquer pessoa que tenha codificado em Python deve ter visto **kwargs. Abreviação de argumentos de palavras-chave. Eles são argumentos passados para funções em uma sintaxe chave = valor. kwargs é usado quando não sabemos o número de argumentos de palavras-chave que serão passados para nossa função. **kwargs é um tipo de dicionário e é tão bom quanto passar um dicionário para uma função. Este dicionário contém:
Seguindo essa lógica, neste artigo, veremos seus casos de uso em Python, construindo até seu caso de uso em FastAPI com classes Pydantic.
Os seguintes pontos serão analisados.
Nota: Não é obrigatório usar kwargs, você pode usar qualquer outra convenção de nomenclatura, por exemplo. **meusArgs, **qualquer coisa etc.
Neste exemplo, teremos uma série de argumentos de palavras-chave passados para uma função como **kwargs e como **kwargs é um dicionário, usaremos o método de dicionário .items() nele. O método .items() retorna um objeto de visualização que exibe uma lista dos pares de tuplas de valores-chave do dicionário.
def print_details(**kwargs): # kwargs is a dictionary containing all keyword arguments print(type(kwargs)) # Output:print(kwargs.items()) # Displays the dictionary items (key-value pairs) # Iterate over the key-value pairs in kwargs for key, value in kwargs.items(): print(f"{key}: {value}") # Calling the function with multiple keyword arguments print_details(name="Stephen", age=30, profession="Software Developer")
Saída
dict_items([('name', 'Stephen'), ('age', 30), ('profession', 'Software Developer')]) name: Stephen age: 30 profession: Software Developer
Como devemos ter notado, as classes Python podem ser chamadas; isso significa que podemos chamar uma classe da mesma forma que chamamos uma função. Chamar uma classe cria uma instância (um objeto) dessa classe.
class Tech: def __init__(self, dev, devops, design): self.dev = dev self.devops = devops self.design = design # Call class to create an instance tech = Tech(dev, devops, design)
Chamar Tech com valores de argumento retornará a instância tech.
Nas classes, o operador ** descompacta o dicionário permitindo que cada par de valores-chave seja passado como um argumento nomeado para o construtor da classe.
No exemplo desta seção, definimos uma classe. Definimos um dicionário com propriedades que correspondem aos parâmetros da classe. Em seguida, criamos uma instância da classe, usando ** para descompactar o dicionário.
class Tech: def __init__(self, dev, devops, design): self.dev = dev self.devops = devops self.design = design # Define a dictionary with properties matching the class's parameters tech_team = { 'dev': 'Stephen', 'devops': ['Jenny', 'Rakeem', 'Stanley'], 'design': 'Carlos' } # Create an instance of the class using ** to unpack the dictionary tech = Tech(**tech_team) print(tech.dev) print(tech.devops) print(tech.design)
O código acima é equivalente a:
class Tech: def __init__(self, dev, devops, design): self.dev = dev self.devops = devops self.design = design # Define a dictionary with properties matching the class's parameters tech_team = { 'dev': 'Stephen', 'devops': ['Jenny', 'Rakeem', 'Stanley'], 'design': 'Carlos' } # Create an instance of the class tech = Tech( dev = tech_team["dev"], devops = tech_team["devops"], design = tech_team["design"] ) print(tech.dev) print(tech.devops) print(tech.design)
Isso ocorre porque:
tech = Tech(**Tech_team)
É o mesmo que:
tech = Tech( dev = tech_team["dev"], devops = tech_team["devops"], design = tech_team["design"] )
Pydantic é uma biblioteca Python usada para validação de dados, é até considerada a biblioteca de validação de dados mais amplamente usada para Python, usando o sistema de dicas de tipo do Python3. Este Pydantic empregado no FastAPI nos ajuda a definir modelos de dados que em termos simples são classes.
Em nossas classes, podemos especificar tipos para nossos atributos ou campos, por exemplo, str, int, float, List. Quando os dados são fornecidos, o Pydantic verifica se eles correspondem.
Além disso, o Pydantic ajuda na análise e serialização. A serialização é o processo de transmissão de objetos de dados em um formato facilmente transmissível; por exemplo, um objeto ou array no formato JSON por sua simplicidade e facilidade de análise.
Pydantic tem uma classe BaseModel da qual as classes definidas herdam. Abaixo está um exemplo de modelo Pydantic:
from pydantic import BaseModel, EmailStr # We import the BaseModel and Emailstr type from Pydantic class UserInDB(BaseModel): username: str hashed_password: str email: EmailStr full_name: Union[str, None] = None
Suponha que temos:
class Item(BaseModel): name:str price:float app = FastAPI() @app.post("/items/") async def create_item(item:Item): return item
No código acima, item que é o parâmetro do corpo da solicitação, é uma instância do modelo Item. Ele é usado para validar e serializar o corpo da solicitação JSON recebida para garantir que ele corresponda à estrutura definida no modelo de item.
Os modelos Pydantic possuem um método .dict() que retorna um dicionário com os dados do modelo.
Se criarmos uma instância de modelo pydantic:
item = Item(name="sample item", price=5.99)
Então chamamos dict() com ele:
itemDict = item.dict() print(itemDict)
Agora temos um dicionário e nossa saída será:
{ "name": "sample item", "price":5.99 }
Observe que:
Item(name="sample item", price=5.99)
É equivalente a
# Using the unpacking operator Item(**itemDict) # Or Item( name=itemDict["name"], price=itemDict["price" )
Veremos agora algumas situações em que usar o operador unpacking é benéfico.
original_dict = {"name": "Stephen", "age": 30, "profession": "Software Developer"} # Creating a new dictionary with additional or modified entries new_dict = {**original_dict, "age": 31, "location": "New York"} print(new_dict)
default_config = {"theme": "light", "notifications": True} user_config = {"theme": "dark"} # Merging dictionaries using unpacking final_config = {**default_config, **user_config} print(final_config)
O operador de descompactação de dicionário ** deve ser considerado devido à sua natureza dinâmica de manipulação de argumentos em funções e classes, e na fusão e criação de novos dicionários. Tudo isso junto leva a menos código e melhor manutenção do código.
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3