I have a mildly surprising snippet which I believe they don't have. It's about interaction of class and instance attributes with behavior of "X += Y". Python expands it to "X = X + Y" but only if X implements "+" but not "+="<p><pre><code> class A:
a = (1,) # tuples are immutable and don't have "+="
b = [1,] # lists have "+="
obj = A()
obj.a += (2,) # this creates obj.a
obj.b += (2,) # this modifies A.b
print(A.a, A.b)
</code></pre>
The snippet prints "(1,) [1,2]".
Hi, maintainer of the repo here, thanks for sharing :)<p>If anyone's willing to go through those examples with an interpreter on the side, you can check out <a href="https://www.wtfpython.xyz/" rel="nofollow">https://www.wtfpython.xyz/</a><p>It's built with pyiodide, the only limitation is you may not get correct results for the examples that are version-dependent. The UX might not be great, especially on mobile (happy to hear ideas on how to improve it), but it does the job for now :)
Walrus operator IMO is a huge mistake. It saves fuck all time/space, but introduces an entire new operator that probably added more complexity, edge cases and quirks than the benefits it provides. <i>Terrible</i> idea.<p>Worse, no one uses it. I've yet to come across anyone that advocates it or remembers it.
I have to write Python for the job right now and this language has pitfalls everywhere. Glad I avoided this language so far.<p>I don't want to use Python for a software more than a few dozen lines or involving multiple developers. This language was designed to unintentionally shoot your foot so many times.
I picked up Python again a couple of months ago, and I am reexperiencing my love/hate relationship with the language.<p>Reading through the documentation in WTFPython I get some kind of affirmation of my bias against python. I hate it, but I also love it, but I hate it. It is just so "je ne sais quoi"--<p>The docs would benefit from some explanations on whys.
> The Walrus operator (:=) was introduced in Python 3.8, it can be useful in situations where you'd want to assign values to variables within an expression.<p>Ok that is infuriating. They dragged their feet through the dirt on how the switch statement is useless and pointless, but then they add some random bullshit like that that nobody ever asked for.
I learned a couple of things there, seems like a very organized way of learning.Just wish more of this approach is implemented by others.<p>Also the discussions in comments makes me wonder if HN should implement syntax highlighting feature.
There are some genuinely surprising ones, but is it just me who seems to think these are for 80% either well-known beginner's mistakes (== vs. is, underscored names) or just begging for problems with operator precedence (by omitting parentheses) and variable scoping (by shadowing variables)?<p>Random example I'm currently reading is: x, y = (0, 1) if True else None, None. The interpreter considers the last None outside the if statement. Gee, so you thought to need parentheses at first but not for the second one, and now it's a pitfall that parentheses are missing? The readme goes so far as so say "I haven't met even a single experience Pythonist till date who has not come across one or more of the following scenarios". Uh huh. Not me.<p>Add parentheses when in doubt, and when not in doubt, add parentheses for readability. In any language. Not excessively, like everyone knows what "if x == 2:" does without them in python, but for anything less obvious or more complicated than a=2*2+3, just do it.
I've seen these before and every single time, it's mostly based on a misunderstanding of certain language features that only a beginner coder would do (for example, not knowing that Python does not do block-level variable scoping, so loop variables leak) or an abuse of an implementation detail (for example, integers under 255 being singletons).<p>"is" is not the same as "==". Confusing the two is a rookie mistake, yet is treated like a "gotcha".
In Python, I've always run into the problem of expression-vs-statement. For example, in my mind I want to do this:<p><pre><code> (a++ if a==b else b++) + 1
</code></pre>
Or something like this (borrowed from <a href="https://stackoverflow.com/questions/65024477/walrus-operator-in-list-comprehensions-python" rel="nofollow">https://stackoverflow.com/questions/65024477/walrus-operator...</a>):<p><pre><code> from datetime import datetime
timestamps = ['30:02:17:36', '26:07:44:25',
'25:19:30:38','25:07:40:47']
timestamps_dt = [
datetime(days=day,hours=hour,minutes=mins,seconds=sec)
for i in timestamps
day,hour,mins,sec := i.split(':')]
</code></pre>
But this type of stuff is always greeted with Python's inflexible syntax. Recently, I learnt about Rackets's idea that "everything is expression" on (<a href="https://beautifulracket.com/appendix/why-racket-why-lisp.html#:~:text=Beautiful%20Racket%20and%20Practical%20Typography,is%20a%20descendant%20of%20Lisp" rel="nofollow">https://beautifulracket.com/appendix/why-racket-why-lisp.htm...</a>.) and was blown away to realize these are valid Racket codes:<p><pre><code> ((if (< 1 0) + *) 42 100)
</code></pre>
or<p><pre><code> (+ 42 (if (< 1 0) 100 200))
</code></pre>
The second one has an equivalent in Python:<p><pre><code> 42 + (100 if 1 < 0 else 200)
</code></pre>
But the first one does not:<p><pre><code> 42 (+ if 1 < 0 else *) 100
</code></pre>
> SYNTAX ERROR.<p>Maybe it's time for me to get my hands dirty with Lisp.
The wtfs about id and is are not deserved. These operations are not used in normal code and are explicitly implementation defined. I suppose they should have named it __is and __id. I don't see why anyone not hacking the interpreter would care about these though
Interesting. I would be interested with a WTFRuby. As I lately explored Ruby deeper, I was surprised that Complex would remove #% as well as most Comparable operators.<p><a href="https://stackoverflow.com/questions/72314247/how-can-ruby-complex-class-have-comparable-in-its-ancestors-when-it-has-none" rel="nofollow">https://stackoverflow.com/questions/72314247/how-can-ruby-co...</a><p><a href="https://stackoverflow.com/questions/71439853/why-ruby-doesn-t-provide-a-complexemodulo-method" rel="nofollow">https://stackoverflow.com/questions/71439853/why-ruby-doesn-...</a>
I've been thinking it would be useful to create a sub-language of python with only essential features (removing hard to explain features such as 'is', ':=', and a plethora of non-essentials) -- that is, fully backward-compatible with python. This would also make restricted interpreters easier to write as well. I know micropython exists, but the goal is more minimal size than simplicity and ease to learn.
That Python uses the exact same string if they contain the same immutable content can probably be a bit confusing. But if you want truly confusing behavior look at how Java treats numbers wrapped in their object type:<p><pre><code> public class Main{
public static void main(String[] args){
Integer a = 300;
Integer b = 300;
System.out.printf(" %s == %s: %s\n", a, b, (a == b));
a = 100;
b = 100;
System.out.printf(" %s == %s: %s\n", a, b, (a == b));
}
}
// output
300 == 300: false
100 == 100: true
</code></pre>
When combined with Java's auto-boxing, this can create some serious confusion
IMHO this is one of the worst ways to improve your Python skills. Instead, focus on what the normal, robust, beautiful, clear, and idiomatic solutions to problems.<p>There is an enormous amount of quality training material available as well as excellent source code to major projects.<p>Most people would be better off just spending a hour or so with the tutorial at docs.python.org.<p>I get people coming to me asking for a job <i>teaching</i> Python when they don't know of some the material in the tutorial. Most have never read the FAQs and aren't aware of common solutions to common problems. To me, if you want to build your skills, start there. Get in the habit of reading docs, even boring ones, and occasionally read some of the source code from your favorite libraries.<p>That said, if you've already a very strong Python programmer, one possible use for these snippets is to help you root out any last, misconceptions of minor details.<p>But, you should resist the urge to show-off or use almost any of these "skills". There are a lot of cute things we can do with chained comparisons, but the only sensible things are: lo <= x <= hi or f(x) == g(x) == h(x). Anything else is too weird for communicating with the human beings. Likewise, you should only use "is" for None tests until you have strong understanding of identity guarantees.