Live data from Hacker News

WTFPython – Understanding Python through surprising snippets

github.com

141–150 of 199 posts

Re: WTFPython – Understanding Python through surprising snippets

#141
post #55

It's a good repo, but remember a lot of those are "A Good Thing™". The first snippet is a very good example: a := "wtf_walrus" doesn't work while: (a := "wtf_walrus") works. It's a fantastic design decision. Python took a long time before getting this operator, because it's a language that favors being readable, easy to use, and above all, to learn. But in many other languages, the very same operator is often misused…

in the zen of python (import this) it says: there should be one-- and preferably only one --obvious way to do it. sadly this is not true for a while in python now. Python became a language that can be really hard to read now.

The many, many ways to print variables inside of a string are testament to that. I remember feeling kind of a chill when the number of methods hit three. Two is an acceptable number of methods if you are transitioning from one form to another as kind of a nod to the growing pains of a language, but at three you have hit some kind of watershed.

Re: WTFPython – Understanding Python through surprising snippets

#142
post #55

Earlier quoted context omitted.

in the zen of python (import this) it says: there should be one-- and preferably only one --obvious way to do it. sadly this is not true for a while in python now. Python became a language that can be really hard to read now.

As a relative newcomer to Python (compared to most, but I do use it professionally every working day for a year, and some non-working days for personal stuff), I find this to be the case. At work I have to use Django, and it's almost a chore to find anything explicit or obvious in it. Its level of abstraction is "Too Damn High" as the meme goes, IMO. It feels like saving boilerplate for the sake of it which just make…

[deleted]

Re: WTFPython – Understanding Python through surprising snippets

#143
post #45

Earlier quoted context omitted.

A while ago, I was also sceptical about the walrus operator, although I use assignments in expressions all the time in C++. But when I was perusing a library written Python the other day, I found five spots in which the walrus operator would make sense - eliminating one line of source code without readability suffering from it.

Is saving 5 lines of code really worth breaking Python's "one way to do it" design principle?

In my work we have code in many places along the lines of:

    data = expensive_function(blah, blah_blah)
    if data:
        # many lines of processing
        data = expensive_function(blah, blah_bah)
And seen a lot of times where newcomers forget the assingment at the end that makes everything move. So yeah, the walrus version would be a lot simpler:

    while data := expensive_function(blah, blah_blah):
        # process data
This is just one of the "edge cases" where the walrus makes sense.

Re: WTFPython – Understanding Python through surprising snippets

#144

Earlier quoted context omitted.

> 1. forget python 2.7 exists But it doesn't work this way. You don't work strictly with the language itself, you work with the whole ecosystem. Libraries, tools, snippets, SO questions, etc. And many of those are still in 2.7 or at least need to specify different solutions for 2.7... It is still a pain.

> Libraries, tools, snippets, SO questions, etc. And many of those are still in 2.7 or at least need to specify different solutions for 2.7... It is still a pain. Admittedly there were some libraries that took a long time to switch, but at this point there is no serious library left, that did not make the switch.

Exactly. I've gone farther even, and this is my motto now:

    Python 3.6+ or burn it to the ground
I mself still have to port a few projects yet, but those that got stuck in 2.7-3.5 land are en route to dying a fiery death, and being reborn in 3.6+ (3.8 where applicable, 3.6 as the lowest I'm willing to accept).

Re: WTFPython – Understanding Python through surprising snippets

#145
post #108

Earlier quoted context omitted.

> the actual creator of the language was so against the addition of this operator that he saw the community’s insistence on it as reason to step down as BDFL. That's backwards. The community was generally opposed to the walrus operator, and Guido stepped down because of (among other things) the community's reaction when he insisted on adding it.

Oh interesting. I’m with the community on this one.

I was too. I've been won over with time.

Not because "Guido", I had the opposite reaction to asyncio, which he designed, enthusiastic at first then I began to see many design flaws.

But because it does make regex matching and reading bytes safely better.

Re: WTFPython – Understanding Python through surprising snippets

#146

It's interesting to see the walrus operator in there. I wonder, is this another example of unnecessary features being added just to claim a bigger change list, or someone really needs this operator? Why would anyone prefer a walrus instead of adding just one more line to their code, which also helps with readability?

You can find a detailed rationale in the relevant PEP: https://www.python.org/dev/peps/pep-0572/#rationale

Re: WTFPython – Understanding Python through surprising snippets

#147
post #79
post #77

Earlier quoted context omitted.

The real WTF here is that you are getting a power output from thee ^ operator, when it actually does xor. Indeed, I've never seen JavaScript mix up operators :) /s

HN isn’t able to render two adjacent asterisk, so I had to make do.

[deleted]

Re: WTFPython – Understanding Python through surprising snippets

#148
post #136

Earlier quoted context omitted.

It's not "python late binding", closures behave this way in any language with mutable bindings[0]. The entire point of a closure is to close over its lexical context, if the lexical context is mutable and mutated before the invocation of the closure, the closure is going to reflect that change. for(var i=0; i x^i); } will behave the same way because it does the same thing, so will e.g. for i := 0; i in Go. One of the…

Works intuitively in golang: https://play.golang.org/p/pn2jBTaTNS8 package main import ( "fmt" ) // return a^n func Power(a, n int) int { var i, result int result = 1 for i = 0; i

I know nothing about go, but it seems to me in your example powers_of_x is a list of n integers, while in the example being discussed is an list of n functions (which can be used to compute the n'th power).

Re: WTFPython – Understanding Python through surprising snippets

#149
post #8

My biggest complaint about Python is that it somehow doesn’t get flak for having the same (if not worse) scoping as JS, which gets endless hate for its function-scoped variables. (So much so that block scoped variables are the new normal in JS, but not in Py!) Take for instance: >>> powers_of_x = [lambda x: x^i for i in range(10)] >>> [f(2) for f in powers_of_x] [512, 512, 512, 512, 512, 512, 512, 512, 512, 512] To m…

I agree totally with that, it's an ugly trap in python, although mitigated by the fact the language doesn't encourage this kind of paradigm so you rarely encounter it. But more absurd than creating a global variable if you forget "var/let/const" ? More absurd than "this" being schizophrenic ? More absurd than having no namespace for 20 years ? That's pushing it.

> I agree totally with that, it's an ugly trap in python, although mitigated by the fact the language doesn't encourage this kind of paradigm so you rarely encounter it.

This. I've made this mistake exactly once in the last 7 years, but that one time almost caused a security issue.

Re: WTFPython – Understanding Python through surprising snippets

#150
post #8

My biggest complaint about Python is that it somehow doesn’t get flak for having the same (if not worse) scoping as JS, which gets endless hate for its function-scoped variables. (So much so that block scoped variables are the new normal in JS, but not in Py!) Take for instance: >>> powers_of_x = [lambda x: x^i for i in range(10)] >>> [f(2) for f in powers_of_x] [512, 512, 512, 512, 512, 512, 512, 512, 512, 512] To m…

This situation is mentioned in the docs:

https://docs.python.org/3.8/faq/programming.html#why-do-lamb...

"This happens because i is not local to the lambdas, but is defined in the outer scope, and it is accessed when the lambda is called — not when it is defined. At the end of the loop, the value of i is 4, so all the functions now return 42, i.e. 16."

These sort of scoping gotchas are pretty common across all programming languages and are a great argument for unit testing. As usual the answer is be more explicit what you're asking the language to do:

>>> powers_of_x = [lambda x, i=i: x*i for i in range(10)]

>>> [f(2) for f in powers_of_x]

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

Note the positional argument with default "i=i."

More discussion:

https://stackoverflow.com/questions/452610/how-do-i-create-a...

Post reply on HN