5 ms·
> But surely Python clamps down on this chicanery, right? > > $ py10 abc.py > 10 is not iterable > string is iterable > [1, 2, 3] is iterable >
by nadavr 4y ago
> But surely Python clamps down on this chicanery, right?
>
> $ py10 abc.py
> 10 is not iterable
> string is iterable
> [1, 2, 3] is iterable
>
> Oh.
>
> Oh my.
I'm sure I'm being dense and missing the obvious but ... what is the author responding to here? What's wrong or bad?
- davesque 4y agoEh, I think they're just overdramatizing things. That's also exactly what I would have expected to happen.
- atoav 4y agoThe only thing that can sometimes bite you here is that str is iterable, if you expect a list of str and you only get a str and suddenly you iterate over the chars. I am not sure if it wouldn't have been better to make the conversion explicit here.
- vitus 4y ago> The only thing that can sometimes bite you here is that str is iterable, if you expect a list of str and you only get a str and suddenly you iterate over the chars. Python isn't even unique in this regard! You can iterate over a string whether you're working in JavaScript, C++, or Go. (And that's not even getting into cases like Haskell where String is merely syntactic sugar for [Char].)
- shadycuz 4y agoHe is just demonstrating that __subclass__ hook has control over what is counted as a match. Which he explained in another article that it allows the author of the abstract class to hijack calls to isinstance for any instances created from subclasses.
- bilboa 4y agoThe point though is that the tone of his article seems to suggest that this is some scary "gotcha" of the language, whereas some of us consider this to just be the expected behavior.
- shadycuz 4y agoWell to me the "gotcha" wasn't that you could control the match from the abstract class, it was all the silly things that you could do. Which for me was the point of the article. I mean the first palindrome example was pretty cool no?
- bobbylarrybobby 4y agoIn the context of this article, the result is not surprising, but in general it's probably not most people's expectation that you can define a class, make sure it doesn't subclass any ABCs, but then still have it "match" an ABC. (If you ask me, cases should only match when types are equal -- pattern matching is structural but (in Python) subtyping is anything but.)
- BerislavLopac 4y agoPython also has structural typing, often called duck typing - if you have a runtime-checkable protocol, an object will also match isinstance even when there is no inheritance.
- rtpg 4y agoWhile I wouldn't go as far as to say that this is "the point" of ABC, it's certainly relatively important, with __subclass_hook__ being promimently placed near the top of the ABC documetnation. Control over destructuring isn't entirely new territory for PLs, Scala has Extractor Objects[0], as an example. I think that it's a bit easy to say "it should just match the type!" when the reality is that even basic classes like list get overwritten in Python. Ultimately many language features have configurable features through dunder methods, and the fact that those get used by other language features is a feature, not a bug IMO. As usual, don't use libraries that do weird stuff... and every once in a while you'll have the nice DSL that does something useful in this space and it will work well. The thought experiment about a more restrictive version of this: how does Python tell that an object is a list? If it's through isinstance, then you're hooking into a bunch of tooling that have hooks that can be overwritten. If it's _not_ through isinstance, suddenly you have multiple ways to test if something is a list (which is a problem). [0]: https://docs.scala-lang.org/tour/extractor-objects.html https://docs.scala-lang.org/tour/extractor-objects.html
- BiteCode_dev 4y agoDuck typing is exactly that, it's core to python.
- Izkata 4y ago> but in general it's probably not most people's expectation that you can define a class, make sure it doesn't subclass any ABCs, but then still have it "match" an ABC. Abstract Base Classes were an attempt to formalize python's duck typing. Matching things that don't inherit from them is their whole purpose.
- deleted 4y ago[deleted]
- deleted 4y ago[deleted]
- radicalbyte 4y agoTo put that in context.. Javascript - the closest competitor - can't even get comparison, numbers or truthiness right....
- seanhunter 4y agoTotally agree. That behaviour is exactly what I would expect. All in all, I really don't get the dramatic tone in this article. It turns out that in python (as in most languages that give you access to the internals) if you mess with the internals the results are well messy. But literally nothing in this article suprised me at all.
- MonkeyMalarky 4y agoI think they're just taking delight from being able to hijack behaviour from elsewhere in the code, using indirect means.
- rmbyrro 4y agoI couldn't avoid having the impression that the author just wanted to show off...
- mannykannot 4y agoI don't think the author is intending to say there is anything wrong in this particular example; he is, rather, anticipating some ways in which this might obfuscate code, either accidentally or deliberately. The rest of the article investigates some of these possibilities and demonstrates that you can, indeed, do so. Perhaps it would have been a bit clearer, and less easy to dismiss as a fuss over nothing, if the author had left the 'not' out of the definition of NotIterable.__subclasshook__(), or defined an IsIterable class with the 'not' in place?