1

I have a Python 2.7 class (call it Child), that is a child of another class (Parent) that is itself a subclass of dict.

I'm trying to define __iter__ in Child in the hopes that when someone does a dict(child_object) I can control how it is converted to a dict. I must be misunderstanding something though, because it seems the dict() call is bypassing calling __iter__ completely and is instead going to the underlying dict.

I did some research and from the dict() method's docs I see that it may be seeing the object as a mapping first, and therefore using that instead of the iterable's __iter__. Is that the case, and if so, is there a way I can overwrite some method that is being called on the mapping?

3
  • 2
    Can you add a simple example to your question? That'd make it much easier to follow what you mean. Commented Oct 16, 2018 at 13:10
  • 1
    Do not inherit from dict, but from collections.UserDict Commented Oct 16, 2018 at 13:12
  • Otherwise special methods won't work, when you override them. Commented Oct 16, 2018 at 13:13

1 Answer 1

3

When you use dict() on a mapping (or use dictionary.update(...) passing in a mapping), then Python will not use __iter__. Python looks for a .keys() method to detect mappings. In that case, if the mapping happens to be a dict or a subclass of dict, then a fast path is picked that copies key-value pairs directly from the underlying C structures. You can't prevent this with custom Python functions.

Put differently, if you must define a custom mapping type that lets you control how dict() copies key-value pairs from it, you should not subclass dict. Implement your own mapping type by subclassing collections.Mapping or collections.MutableMapping or a class from the UserDict module.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, that confirms my suspicions. I saw UserDict docs say "The need for this class has been largely supplanted by the ability to subclass directly from dict" so I went for dict.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.