On Sat, Apr 24, 2021 at 10:14 AM Nick Coghlan <ncoghlan@gmail.com> wrote:
On Sat, 24 Apr 2021, 10:02 am Skip Montanaro, <skip.montanaro@gmail.com> wrote:
Practically speaking, one issue I have is how easy it is to write isinstance or issubclass checks. It has historically been much more difficult to write and maintain a check that something looks like a duck.
`if hasattr(foo, 'close') and hasattr(foo, 'seek') and hasattr(foo, 'read'):`
Just does not roll off the figurative tongue and that is a relatively simple example of what is required for a duck check.
To prevent isinstance use when a duck check would be better,
I'm going to chime in briefly then return to lurking on this topic, trying to figure out all the changes to typing while I wasn't paying attention. Back in ancient times I recall "look before you leap" as the description of either of the above styles of checks, no matter which was easier to type. At the time, I thought the general recommendation was to document what attributes you expected objects to provide and just make the relevant unguarded references. I no longer recall what the tongue-in-cheek description of that style was (just "leap"?) Is that more simple usage more akin to classic "duck typing" than always guarding accesses? I assume that will still have a place in the pantheon of Python type variants.
LBYL: Look before you leap (check then use) EAFP: Easier to ask forgiveness than permission (use, then handle any exceptions or let them escape)
(for accessing external resources rather than satisfying internal type consistency, you usually need the latter, as the external state may change between checking and usage)
Duck typing usually falls squarely into the EAFP category.
Isn't it orthogonal? LBYL means checking first, EAFP means going ahead and doing things, and coping with failure. Duck typing means caring about it having a specific method/attribute, nominal typing means caring about it "being a list". You can test either form in advance, and you can certainly duck-type in EAFP style, so there's only one quadrant that might not be possible (and even that, I'm sure, would be possible somehow). ChrisA