Reputation: 20648
I have a dictionary as follows
my_dict = {
"key_1": "value_1",
"key_2": {
"key_1": True,
"key_2": 1200
}
"key_3": True,
}
and in my class
@dataclass
class TestClass:
my_dict: typing.Dict[{str, str}, {str, typing.Dict[{str, bool}, {str, int}]}]
The above declaration is incorrect.
If I want to add typing for my_dict what it should be and how to write the structure since I am having different types as values?
Upvotes: 4
Views: 2797
Reputation: 409
Since Python 3.8, we have TypedDict
that could very well solve what you need:
from dataclasses import dataclass
from typing import TypedDict
class NestedDictType(TypedDict):
key_1: bool
key_2: int
class TopLevelDictType(TypedDict):
key_1: str
key_2: NestedDictType
key_3: bool
@dataclass
class TestClass:
my_dict: TopLevelDictType
Upvotes: 0
Reputation: 5385
I'll take a stab it it. So, the type of the values looks to be pretty distinct and easy to determine at runtime. The code that accesses the dictionary data and performs some action on it dependent on its type can use instanceof() in an if/elif/else block.
def some_method(self, key):
val = self.my_dict[key]
if isinstance(val, str): # fixed from instanceof to isinstance...
print val
elif isinstance(val, dict):
print "it was a dictionary"
else:
print "Guess it must have been an int or bool."
or you could test for type like so: if type(val) is str: dosomething()
Upvotes: 1
Reputation: 15905
You want to use a Union
as the value for the dictionary:
from typing import Dict, Union
@dataclass
class TestClass:
my_dict: Dict[str, Union[str, bool, int]]
The union informs the typechecker that values in the dictionary must be either str
s, bool
s, or int
s. When getting values, you'll want to use isinstance
to determine what to do with a value:
if isinstance(self.my_dict['a'], str):
return self.my_dict['a'].encode('utf-8')
else isinstance(self.my_dict['a'], bool):
return not self.my_dict['a']
else:
return self.my_dict['a'] / 10
If you know that a key will contain a specific type, you can avoid the typechecker's complaints by using cast
:
from typing import cast
value = cast(bool, self.my_dict['some_bool'])
Upvotes: 4