如何在Python中键入嵌套对象的提示?

时间:2019-12-27 09:50:48

标签: python-3.x type-hinting zeep

我目前正在与WSDL集成,因此决定使用Zeep库与Python一起使用。

我试图对响应中的mypy进行类型提示,以便它可与VSCode的Intellisense一起使用,并且我不会进行粗心的分配或修改。但是,当WSDL响应位于嵌套对象中时,我遇到了障碍,并且我无法找到一种提示它的方法。

示例响应:

{
    'result': {
        'code': '1',
        'description': 'Success',
        'errorUUID': None
    },
    'accounts': {
        'accounts': [
            {
                'accountId': 1,
                'accountName': 'Ming',
                'availableCredit': 1
            }
        ]
    }
}

我正在使用以下代码段进行提示:

class MethodResultType:
    code: str
    description: str
    errorUUID: str

class AccountType:
    accountId: int
    accountName: str
    availableCredit: float

class getAccounts:
    result: MethodResultType
    accounts: List[AccountType] # Attempt 1
    accounts = TypedDict("accounts", {"accounts": List[AccountType]}) # Attempt 2

client = Client(os.getenv("API_URL"), wsse=user_name_token)
accountsResponse: getAccounts = client.service.getAccounts()
accounts = accountsResponse.accounts.accounts


# Attempt 1: "List[AccountType]" has no attribute "accounts"; maybe "count"?
# Attempt 2: "Type[accounts]" has no attribute "accounts"

对于尝试1,原因很明显。但是尝试了尝试2之后,我不知道该如何继续了。我在这里想念什么?

2 个答案:

答案 0 :(得分:6)

来自评论会话的更新

  1. 您将需要每个类都是TypedDict的子类。像class Foo(TypedDict)之类的东西。
  2. errorUUIDOptional[str]
  3. accounts的类型为Dict[str, List[AccountType]],因为它具有内部(也可能是冗余的)密钥,也称为accounts
  4. 您需要使用带有加粗键的方括号来访问键-accountsResponse['accounts']['accounts']

这是一个建议的解决方案:

from typing import List, TypedDict, Optional, Dict

class MethodResultType(TypedDict):
    code: str
    description: str
    errorUUID: Optional[str]

class AccountType(TypedDict):
    accountId: int
    accountName: str
    availableCredit: float

class getAccounts(TypedDict):
    result: MethodResultType
    accounts: Dict[str, List[AccountType]]

result: getAccounts = {
    'result': {
        'code': '1',
        'description': 'Success',
        'errorUUID': None
    },
    'accounts': {
        'accounts': [
            {
                'accountId': 1,
                'accountName': 'Ming',
                'availableCredit': 1
            }
        ]
    }
}

查看此MyPy游乐场: https://mypy-play.net/?mypy=latest&python=3.8&gist=dad62a9e2cecf4bad1088a2636690976

TypedDict是MyPy的扩展,请确保安装MyPy(加上扩展名)并导入TypedDict:from typing_extensions import TypedDict

从Python 3.8中,您可以直接从键入模块中导入TypedDict。

https://mypy.readthedocs.io/en/latest/more_types.html#typeddict https://www.python.org/dev/peps/pep-0589/

答案 1 :(得分:0)

使用此answer作为参考,以下内容适用于我的情况(VSCode中的Intellisense,如果直接分配给变量,则不起作用):

更新:使用另一个answer作为参考,我更新了代码,使其能够同时工作。 (VSCode中的Intellisense,直接分配给变量)

socket.id