I have a simple code snippet where I set dictionary values as empty lists:
new_dict = {}
for i in range(1, 13):
new_dict[i] = []
Now, if inside the loop on the next line I would type new_dict[i] and add a dot, I expect PyCharm to show me a list of methods available for a list, but PyCharm fails to recognize the dictionary value type in this simple case:
Why is it happening and what can I do? Using PyCharm 2016.1.2, Python 2.7.10.
As a workaround, I can explicitly add a type hint, letting PyCharm know that new_dict is a dictionary where keys are integers and values are lists by adding a # type: dict[int, list] inline comment:
解决方案
Lets consider a slightly more complex scenario with a variable:
for i in range(10):
if i%2:
x = 3
else:
x = "hello"
x. #type hint for both int and str
In this case the last line will give us all the methods of ints and strs because PyCharm is able to detect that x will either be an int or a str
Now replace all the occurences of x with my_dict[i]:
my_dict = {}
for i in range(10):
if i%2:
my_dict[i] = 3
else:
my_dict[i] = "hello"
my_dict[i]. #no type hint :(
All of the same rules apply as above, we know (and PyCharm would be able to figure out) that my_dict[i] is either going to be an int or a str.
However what would you expect to happen if you were not initializing the dict?
def f(my_dict): #or even (my_dict:dict)
my_dict[1]. #cannot possibly expect a type hint
In this case there is no way to know what the values of the dict are other then adding an explicit annotation just like you would in your example case:
def f(my_dict:"dict[int,list]"):
my_dict[1]. #get all the list methods
This really reinforces some lines from The Zen of Python:
Explicit is better than implicit.
Readability counts.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
(I include readability because the explicit type hint is a lot easier to read then a potentially buried assignment)