Home > Back-end >  Why is fromkeys a method rather than a built-in function?
Why is fromkeys a method rather than a built-in function?

Time:03-29

Why is the fromkeys method of the dict class a method of the class rather than a stand alone built-in function?

As much as I'm aware, it only returns a new dictionary based on the parameters passed to the method, and is not impacted by the class instance (dictionary) it is called from. The usual implementation just uses the class name dict directly rather than specifying a class instance in the first place.

I've tried the following statements but they all have consistently ignored the class instance as I mentioned.


>>> dict.fromkeys((1,2))

{1: None, 2: None}

>>> {1: "Hey"}.fromkeys((1,2))

{1: None, 2: None}

>>> {1: "Hey"}.fromkeys((2,))

{2: None}

The Python documentation also doesn't mention anything more than what the parameters do. It does not mention any use of the class instance but does not declare its purposelessness either.

I believe the reason is probably related to the namespace management. A function fromkeys created by the user will not affect the built-in class method this way, right?

I just wanna make sure I've not missed out any purpose the class instance could have, to avoid future bugs in my codes

CodePudding user response:

The result of dict.from_keys only relies on dict itself and the arguments passed to the function. It doesn't use any of the information stored in an existing instance, so there is no reason to supply one.

As for why it is not a function, dict.from_keys can still work for subclasses of dict without having to do anything differently.

>>> from collections import OrderedDict
>>> type(OrderedDict.fromkeys([1,2,3]))
<class 'collections.OrderedDict'>

Counter.fromkeys won't work, but that's because Counter.fromkeys is specifically overriden to suggest an alternative.


Roughly speaking, you can think of dict.fromkeys as being implemented like this:

@classmethod
def fromkeys(cls, keys, value=None):
    return cls((k, value) for k in keys)

A call like

{'a': 1}.fromkeys(['b'])

is equivalent to

dict.fromkeys(dict, ['b'])  # First argument is type({'a': 1}), not dict
  • Related