Python 中的 ** 运算符是上下文相关的或取决于它的使用对象;当与数字一起使用时(通常在两个数字之间),它用作 求幂运算符 。然而,在本文中,我们将研究使用它的另一个上下文。我们将研究它作为解包运算符的用途,用于解包Python字典。
任何用 Python 编写过代码的人都一定见过 **kwargs。关键字参数的缩写。它们是以 key = value 语法传递给函数的参数。当我们不知道将传递到函数中的关键字参数的数量时,使用 kwargs。 **kwargs 是一种字典类型,与将字典传递给函数一样好。该词典包含:
按照这个逻辑,在本文中,我们将研究它在 Python 中的用例,并构建它在具有 Pydantic 类的 FastAPI 中的用例。
将关注以下几点。
注意:不强制使用 kwargs,您可以使用任何其他命名约定,例如**myArgs,**任何东西等等
在这个例子中,我们将有许多关键字参数作为 **kwargs 传递给函数,并且由于 **kwargs 是一个字典,我们将在其上使用字典方法 .items() 。 .items() 方法返回一个视图对象,该对象显示字典的键值元组对的列表。
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")
输出
dict_items([('name', 'Stephen'), ('age', 30), ('profession', 'Software Developer')]) name: Stephen age: 30 profession: Software Developer
我们一定已经注意到,Python 类是可调用的;这意味着我们可以像调用函数一样调用类。调用一个类会创建该类的一个实例(对象)。
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)
使用参数值调用 Tech 将返回实例 tech。
在类中, ** 运算符解包字典,允许每个键值对作为命名参数传递给类构造函数。
在本节的示例中,我们定义了一个类。我们定义一个字典,其属性与类参数匹配。然后我们创建该类的一个实例,使用 ** 来解压字典。
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)
上面的代码相当于:
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)
这是因为:
tech = Tech(**Tech_team)
等同于:
tech = Tech( dev = tech_team["dev"], devops = tech_team["devops"], design = tech_team["design"] )
Pydantic是一个用于数据验证的Python库,通过使用Python3的类型提示系统,它甚至被誉为Python中使用最广泛的数据验证库。 FastAPI 中使用的 Pydantic 帮助我们定义数据模型,简单来说就是类。
在我们的类中,我们可以为属性或字段指定类型,例如 str、int、float、List。提供数据后,Pydantic 会进行检查以确保其匹配。
除此之外,Pydantic 还有助于解析和序列化。序列化是将数据对象传输为易于传输的格式的过程;例如,将对象或数组转换为 JSON 格式,以使其简单且易于解析。
Pydantic 有一个 BaseModel 类,定义的类继承自该类。以下是 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
假设我们有:
class Item(BaseModel): name:str price:float app = FastAPI() @app.post("/items/") async def create_item(item:Item): return item
在上面的代码中,item是请求体参数,是Item模型的一个实例。它用于验证和序列化传入的 JSON 请求正文,以确保其与 Item 模型中定义的结构匹配。
Pydantic 模型有一个 .dict() 方法,它返回包含模型数据的字典。
如果我们创建一个 pydantic 模型实例:
item = Item(name="sample item", price=5.99)
然后我们用它调用 dict():
itemDict = item.dict() print(itemDict)
我们现在有一个字典,我们的输出将是:
{ "name": "sample item", "price":5.99 }
注意:
Item(name="sample item", price=5.99)
相当于
# Using the unpacking operator Item(**itemDict) # Or Item( name=itemDict["name"], price=itemDict["price" )
我们现在将看看使用拆包运算符是有益的一些情况。
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)
字典解包运算符 ** 是值得考虑使用的一个,因为它具有处理函数和类中的参数以及合并和创建新字典的动态特性。所有这些放在一起可以减少代码并更好地维护代码。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3