2

I am trying to store files in a dictionary depending on their type. For this, I am using pygments API as follow:

# Initialization of the self.files dictionary
self.files = dict()
# Scanning and categorizing the files
for file in files:
    lexer = guess_lexer__for_filename(file, None)
    if type(lexer) in self.files:
        self.files[type(lexer)].append(file)
    else:
        self.files[type(lexer)] = [file]

But, now, when passing this code through pylint3, I get a warning telling me that I should use isinstance() in place of type() (unidiomatic-typecheck).

The best way to workaround this warning I found so far is as follow:

self.files = dict()
for file in files:
    lexer = guess_lexer__for_filename(file, None)
    if lexer.__class__ in self.files:
        self.files[lexer.__class__].append(file)
    else:
        self.files[lexer.__class__] = [file]

But, does it really solve the problem ? And, moreover, I started to doubt that using a type as a key in a dictionary is robust enough.

So, is there more suitable and robust ways to do? Any solution with good arguments is welcome.

perror
  • 7,071
  • 16
  • 58
  • 85

1 Answers1

3

Using the type() output, an object, as a key is just fine. Ignore that warning in this case.

I'd use dict.setdefault() or collections.defaultdict() to extend the list value:

self.files = {}

for file in files:
    lexer = guess_lexer__for_filename(file, None)
    self.files.setdefault(type(lexer), []).append(file)

or

from collections import defaultdict

self.files = defaultdict(list)

for file in files:
    lexer = guess_lexer__for_filename(file, None)
    self.files[type(lexer)].append(file)

However, on Python 3, you could investigate if functools.singledispatch() could be used to handle your use-case instead. It calls a registered function for a given object type, taken from the first argument, and supports subclasses.

Community
  • 1
  • 1
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • The `singledispatch()` is nice but it is not fitting the usage I intend to have. And, I did not know the `setdefault`/`defaultdict` trick and I will definitely use it. Thanks a lot ! – perror Jan 27 '16 at 16:21