如何在 Python 中键入提示嵌套对象? [英] How can I type-hint a nested object in Python?

查看:38
本文介绍了如何在 Python 中键入提示嵌套对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm currently doing a integration with WSDL, and such decided to go with Python using the Zeep library.

我正在尝试使用 mypy 对响应进行建模,以便它可以与 VSCode 的 Intellisense 配合使用,并且在我进行粗心的分配或修改时会给出一些提示.但是,当 WSDL 响应位于嵌套对象中时,我遇到了障碍,而且我无法找到对其进行类型提示的方法.

I'm trying to model the response with mypy, so that it works with VSCode's Intellisense, as well as some giving me hints when I'm doing careless assignments or modifications. But I hit a roadblock when the WSDL responses is in a nested object, and I can't figure a way to type-hint it.

来自 WSDL 的示例响应:

Sample response from WSDL:

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

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

I'm using the following snippet to type-hint:

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 之后,我不知道如何继续了.我在这里错过了什么?

For Attempt 1, the reason is obvious. But after trying Attempt 2, I don't know how to proceed anymore. What am I missing here?

更新:按照@Avi Kaminetzky 的 answer,我尝试了以下 (游乐场):

Update: Following @Avi Kaminetzky's answer, I tried with following (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 收到错误消息:

But I'm getting error message from mypy:

"getAccounts" has no attribute "result"
"getAccounts" has no attribute "accounts"

推荐答案

使用此 answer 作为参考,以下内容适用于我case(VSCode 中的智能感知,如果直接赋值给变量则不起作用):

Using this answer as reference, the following works for my case (Intellisense in VSCode, not working if directly assign into a variable):

更新:使用另一个 answer 作为参考,我已经更新了我的代码,以便能够以两种方式工作.(VSCode中的Intellisense,直接赋值给一个变量)

Update: Using another answer as reference, I have updated my code to be able to work both ways. (Intellisense in VSCode, directly assign into a variable)

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

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

class accounts:
    accounts: List[AccountType]

class getAccounts:
    def __init__(self):
        self.accounts = accounts()
    result: MethodResultType
    @property
    def accounts(self):
        return self.accounts


client = Client(os.getenv("API_URL"), wsse=user_name_token)


# Getting real response from WSDL
accountsResponse: getAccounts = client.service.getAccounts()


# For testing using sample response
sampleResponse: getAccounts = getAccounts({
    'result': {
        'code': '1',
        'description': 'Success',
        'errorUUID': None
    },
    'accounts': {
        'accounts': [
            {
                'accountId': 1,
                'accountName': 'Ming',
                'availableCredit': 1
            }
        ]
    }
})

这篇关于如何在 Python 中键入提示嵌套对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆