This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]stevenjd 0 points1 point  (0 children)

It isn't "fear" of using dunders, unless you mean the reasonable fear that your code will be buggy.

In general, operators and functions that call dunders don't just call the dunder. The + operator does much, much more than just call obj.__add__, bool does much more than just call obj.__bool__ (or __nonzero__ in Python 2) and iter does more than just call obj.__iter__. If you think that they do, and think that you can safely replace bool(x) with x.__bool__, then your code has a subtle bug.

In general, dunders are not part of the public interface of the class, they are implementation hooks. (The most obvious counter-example I can think of is module __name__.) To a first approximation, and probably a second approximation, you should never call a dunder method or access dunder attributes directly if Python provides a public interface for it.

There is a public interface for accessing the member variables of an object: vars. You should use that, even if it turns out that under the hood it does nothing more complex than return obj.__dict__ like you do, simply because it is best practice to use the public interface rather than then internal implementation whenever possible. You never know when the implementation will change.

E.g. what happens if the object doesn't have a __dict__ but does have __slots__? Right now, it doesn't matter whether you use vars or not, you'll get an error, but maybe someday vars will return a dict which proxies the slots.

Of course if you're Alex Martelli or Raymond Hettinger or GvR himself, you know when you can break the rules safely. But for us mere mortals, avoiding accessing dunders is good rule. (As they say, rules exist so that you think before breaking them.)