python - 如何在 Python 中对嵌套对象进行类型提示?

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

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

我正在尝试使用 mypy 对响应进行建模, 这样它就可以与 VSCode 的 Intellisense 一起使用,并且在我进行粗心的分配或修改时给我一些提示。但是当 WSDL 响应位于嵌套对象中时,我遇到了障碍,我想不出一种方法来输入提示。

来自 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 之后,我不知道如何进行了。我在这里想念什么?

更新:
关注@Avi Kaminetzky 的 answer ,我尝试了以下(playground):

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
            }
        ]
    }
}

print(result.result)
print(result.accounts)


但我从 mypy 收到错误消息:
"getAccounts" has no attribute "result"
"getAccounts" has no attribute "accounts"

最佳答案

来自评论中对话的更新

  • 您将需要每个类都是 TypedDict 的子类。像 class Foo(TypedDict) .
  • errorUUIDOptional[str] .
  • accounts是类型 Dict[str, List[AccountType]]因为它有一个内部(可能是冗余的)键,也称为 accounts .
  • 您需要使用带有字符串化键的方括号来访问键 - 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/

    关于python - 如何在 Python 中对嵌套对象进行类型提示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59498869/

    相关文章:

    Python 3 同时运行多个函数

    python - 将值从一个 python 脚本返回到另一个

    php - php 中的对象类型提示

    python - 类型提示中的可选联合

    python - 如何仅键入协议(protocol)方法的第一个位置参数并让其他参数不键入?

    python - Django channel : Alternative of Redis for windows machine?

    python - 如何将 python 脚本 cmd 输出重定向到文件?

    python - 使用css选择器使用scrapy在Reactjs页面上抓取嵌套标签

    python - NLTK 句子边界错误

    python-3.x - 有没有办法计算 Pandas 数据框中不同行数的前瞻性滚动值?