web-dev-qa-db-ja.com

Pythonでネストされたオブジェクトをタイプヒントするにはどうすればよいですか?

私は現在WSDLとの統合を行っており、Zeepライブラリを使用してPython.

VSCodeのIntellisenseで動作するようにmypyで応答をモデル化しようとしています。また、不注意な割り当てや変更を行っているときにヒントを示すものもあります。しかし、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"
5
Tan Jia Ming

この answer を参照として使用すると、次のように機能します(VSCodeのIntellisense、変数に直接割り当てると機能しません)。

更新:別の answer を参照として使用して、両方の方法で機能するようにコードを更新しました。 (VSCodeのIntellisense、変数に直接割り当てる)

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

0
Tan Jia Ming