13 ms·
What's Coming in Python 3.8
- GrumpyNl 7y agoWhy elif en not juste elseif?
- mehrdadn 7y agoOr just else if... but honestly elif is easiest to type and it's not hard to understand.
- reallydude 7y agoHard is being used in a "type the keys" sense. It's more complexity to borrow idioms from languages then slightly change the syntax (PHP!), which isn't necessary. Like most languages, choices are made without evidence (but plenty of anecdotes and personal style).
- akubera 7y agoPerhaps to align with the final "else" clause, or it was familiar to c programmers due to the c-preprocessor directive https://gcc.gnu.org/onlinedocs/cpp/Elif.html https://gcc.gnu.org/onlinedocs/cpp/Elif.html, or they were mindful that every character counts when you want to push 80 character max-line-length style? To be clear, that's not a new feature in 3.8.
- dreary_dugong 7y agoIt fits in a single indent space. At least that's what my professor told us, and it seems to be confirmed by a quick online search.
- dec0dedab0de 7y agoI dont like the positional only arguments.. Really, I dont like anything that trys to force a future developer into using your code the way you expect them to.
- nneonneo 7y agoOne of the use-cases for positional-only arguments strikes me as being very sensible: def my_format(fmt, *args, **kwargs): ... fmt.format(*args, **kwargs) suffers from a bug if you want to pass fmt as a keyword argument (e.g. `my_format('{fmt}', fmt='int')`). With positional-only arguments that goes away. You could always force developers into using your code the way you expect by parsing args/kwargs yourself, so it's not like this really changes anything about the "restrictiveness" of the language.
- duckerude 7y agoI think the main value is that function documentation becomes slightly less absurd. If you run `help(pow)` as early as Python 3.5 it lists the signature as `pow(x, y, z=None, /)`. The first time I saw that `/` I was pretty confused, and it didn't help that trying to define a function that way gave a syntax error. It was this weird thing that only C functions could have. It's still not obvious what it does, but at least the signature parses, which is a small win. Another thing it's good for is certain nasty patterns with keyword arguments. Take `dict.update`. You can give it a mapping as its first argument, or you can give it keyword arguments to update string keys, or you can do both. If you wanted to reimplement it, you might naively write: def update(self, mapping=None, **kwargs): ... But this is wrong. If you run `d.update(mapping=3)` you won't update the 'mapping' key, you'll try to use `3` as the mapping. If you want to write it in pure Python < 3.8, you have to do something like this: def update(*args, **kwargs): if len(args) > 2: raise TypeError self = args[0] mapping = None if len(args) == 2: mapping = args[1] ... That's awful. Arguably you shouldn't be using keyword arguments like this in the first place. But they're already used like this in the core language, so it's too late for that. Might as well let people write this: def update(self, mapping=None, **kwargs, /): ...
- philsnow 7y agoI noticed some changes to pickle; do people still use pickle for Real Work? Potential vulnerabilities aside, I got bitten by some migration issue back in the 2.2 to 2.4 transition where some built-in types changed how they did their __setstate__ and __getstate__ (iirc) and that caused objects picked under 2.4 to not unpickle correctly under 2.2 or something like that. After that I never wanted to use pickle in production again.
- brilee 7y agoPickle is only guaranteed to work within python versions and shouldn't be used as a long-term data storage strategy. It's really intended for quick-n-dirty serialization, or for multiprocessing communication, where the objects are ephemeral.
- gonational 7y agoI recommend a talk from Pycon 2019, wherein Dustin Ingram explains PEP-572 (aka the Walrus Operator) better than I’ve seen done elsewhere. IMHO, the usefulness of this new operator outweighs the slight learning curve required to get past the awkwardness you will experience when you are first acquainted to it. Here is that talk: https://youtu.be/6uAvHOKofws https://youtu.be/6uAvHOKofws
- guicho271828 7y agosmh
- gclaugus 7y agoWalrus operator looks like a great addition, not too much syntax sugar for a common pattern. Why were folks arguing about it?
- joshuamorton 7y agoIt's not that common. There's 1 place where its useful imo (comprehensions to avoid duplicate calls), but even that can be handled case by case, and it certainly isn't a common thing.
- theli0nheart 7y agoDisagree. In my experience (albeit, not very long, been writing Python since 2007 or so), assigning to a value and checking for truthiness is a very common pattern.
- noname120 7y agoVery common pattern, confusing nonetheless. It does two different things at once where traditionally Python is explicit and only does one thing at once.
- nerdponx 7y agoThis is probably the one argument against it that I agree with: I don't actually like it when I see it in other languages!
- coldtea 7y agoIt's extremely common. I've had to use a workaround for that every time I've tested a regular expression match that I wanted to process for example. Also problematic in comprehensions...
- hdfbdtbcdg 7y agoBecause it goes against 20 years of the principles behind the language.
- sleavey 7y agoWithout wanting to ignite a debate about the walrus operator (and having not read any of the arguments), I can guess why there was one. It's not clear to me what it does just from reading it, which was always one of Python's beginner-friendlinesses.
- coldtea 7y ago>It's not clear to me what it does just from reading it How isn't it entirely obvious? := is the assignment operator in tons of languages, and there's no reason not to have assignment be an expression (as is also the case in many languages).
- sleavey 7y agoIt's not in a language I've ever used (furthermore, I explicitly mentioned beginners in my comment).
- coldtea 7y agoWell, beginners wont know generators, list comprehensions, asyncio, keyword arguments, and tons of other things either...
- txcwpalpha 7y ago> := is the assignment operator in tons of languages It is? Which ones? Other than Go, I can not think of a single language that has ":=" as an operator. Java does not, JavaScript does not, C/C++ do not, Ruby does not, I don't think PHP does, Erlang/Elixir do not, Rust does not... (I could be wrong on these, but I've personally never seen it in any of these languages and I can't find any mention of it in these languages' docs). I tried looking around the internet at various popular programming languages and the only ones I could find that use ":=" are: Pascal, Haskell (but it's used for something else than what Python uses it for), Perl (also used for something else), and Scala (but in Scala it isn't officially documented and doesn't have an 'official' use case). I don't have a strong opinion about ":=" in Python but I do agree that it's unintuitive and thus not very "Pythonic".
- traderjane 7y agohttps://docs.python.org/3.8/whatsnew/3.8.html https://docs.python.org/3.8/whatsnew/3.8.html
- ehsankia 7y agoI don't know why the downvotes, but I personally much prefer this to the editorialized and incomplete list in the current list. Looking at the module changes, I think my top pick is the changes to the `math` module: > Added new function math.dist() for computing Euclidean distance between two points. > Added new function, math.prod(), as analogous function to sum() that returns the product of a ‘start’ value (default: 1) times an iterable of numbers. > Added new function math.isqrt() for computing integer square roots. All 3 are super useful "batteries" to have included.
- deleted 7y ago[deleted]
- voldacar 7y agoPython looks more and more foreign with each release. I'm not sure what happened after 3.3 but it seems like the whole philosophy of "pythonic", emphasizing simplicity, readability and "only one straightforward way to do it" is rapidly disappearing.
- baq 7y agoi've been hearing this since 1.5 => 2.0 (list comprehensions), then 2.2 (new object model), 2.4 (decorators)... happy python programmer since 1.5, currently maintaining a code base in 3.7, happy about 3.8.
- runxel 7y agoThat's especially funny given how everybody screams "that's not pythonic!!1!" nowadays when somebody does _not_ use a list comprehension...
- spamizbad 7y agoI cut my teeth on 2.2-2.4 and remember getting my hand slapped when 2.4 landed and I used a decorator for the first time. It was to allow only certain HTTP verbs on a controller function. A pattern adopted by most Python web frameworks today.
- sametmax 7y agoMost code still look like traditional Python. Just like meta programming or monkey patching, the new features are used sparingly by the community. Even the less controversial type hints are here on maybe 10 percent of the code out there. It's all about the culture. And Python culture has been protecting us from abuses for 20 years, while allowing to have cool toys. Besides, in that release (and even the previous one), appart from the walrus operator that I predict will be used with moderation, I don't see any alien looking stuff. This kind of evolution speed is quite conservative IMO. Whatever you do, there there always will be people complaining I guess. After all, I also hear all the time that Python doesn't change fast enough, or lack some black magic from functional languages.
- stakhanov 7y agoSpeaking as someone who has written Python code almost every day for the last 16 years of my life: I'm not happy about this. Some of this stuff seems to me like it's opening the doors for some antipatterns that I'm consistently frustrated about when working with Perl code (that I didn't write myself). I had always been quite happy about the fact that Python didn't have language features to blur the lines between what's code vs what's string literals and what's a statement vs what's an expression.
- sametmax 7y agoF-strings have appeared 2 versions ago. All in all, the feedback we have has been overwhelmingly positive, including on maintenance and readability.
- theplague42 7y agoI second this. F-strings make string formatting so much more concise. I'm excited about the walrus operator for the same reason.
- agumonkey 7y agof-strings allow mutation ? mutation is tricky, a whole field of programming language research is built on avoiding mutation
- mr_crankypants 7y agoNot just more concise; less error prone. A reasonably large number of the bugs I encounter relate to the order or number of formatting arguments not matching the slots in the format string. It's pretty hard to make that kind of mistake with an fstring.
- sleavey 7y agoI love f-strings. I just wish tools like pylint would shut up when I pass f-strings to the logging module. I as the developer understand and accept the extra nanosecond of processor time to parse the string that might not be logged anywhere!
- jasonrhaas 7y agoThe walrus operator does not feel like Python to me. I'm not a big fan of these types of one liner statements where one line is doing more than one thing. It violates the philosophies of Python and UNIX where one function, or one line, should preferably only do one thing, and do it well. I get the idea behind the :=, but I do think it's an unnecessary addition to Python.
- coldtea 7y ago>It violates the philosophies of Python and UNIX where one function, or one line, should preferably only do one thing, and do it well. Python never had that philosophy... You might confused it with "there should be one, and preferably only one, obvious way to do anything".
- andrewf 7y agoThis has never felt like a Pythonic principle to me. Python has always seemed like a high-level language that enables dense code. Look at the docs for list comprehensions! https://docs.python.org/2/tutorial/datastructures.html#list-comprehensions https://docs.python.org/2/tutorial/datastructures.html#list-... A lot of folks see Go as a Python successor which surprises me because I don't think the languages favor the same things at all. Maybe my perspective is weird.
- jstimpfle 7y agoI support your view, but want to make you aware that early unix did favour a little cleverness to reduce line counts (and even character counts). C's normal assignment operator does what python's walrus does, for example. Or look at pre/post increment/decrement operators. Or look at languages like sed, or bc, they try to be terse over anything else.
- fatbird 7y agoThe unix philosophy of simplicity was on a per tool basis, not function or line of code. The walrus operator is Python version of what we can do now in C or in JS, doing plain assignment in an expression while evaluating it for truthiness. And more often than not, the point of that single-purposeness in Unix is so you can chain a bunch of piped commands that result in a perl-like spaghetti command that's three terminal widths long.
- mottosso 7y agoVery much looking forward to assignment expressions! It's something I've wanted to do every so often, only to realise that you can't. A worthy addition to the already intuitive Python language.
- tomd3v 7y agoSeriously. I recently came from PHP, and this is one feature I've been missing quite often and a lot.
- Alex3917 7y agoHave there been any performance benchmarks done on Python 3.8 yet? I'd be interested in seeing how it compares to 3.6 and 3.7, but haven't seen anything published.
- gonational 7y agoAbsolutely this. I think that the most important thing Python can do in each release is to improve performance, incrementally.
- tasty_freeze 7y agoI'm all in favor of the walrus operator for the for loop, but the first example given to justify it is code I'd never write. The first if does a return, so there is no need for the else: and indentation. I'm sure there are other code examples that would justify it, but this one is unconvincing.
- duckerude 7y agoThe return statements make it a poor example. There's an example from the standard library in the PEP that has a similar shape: reductor = dispatch_table.get(cls) if reductor: rv = reductor(x) else: reductor = getattr(x, "__reduce_ex__", None) if reductor: rv = reductor(4) else: reductor = getattr(x, "__reduce__", None) if reductor: rv = reductor() else: raise Error( "un(deep)copyable object of type %s" % cls) Becomes: if reductor := dispatch_table.get(cls): rv = reductor(x) elif reductor := getattr(x, "__reduce_ex__", None): rv = reductor(4) elif reductor := getattr(x, "__reduce__", None): rv = reductor() else: raise Error("un(deep)copyable object of type %s" % cls)
- wodenokoto 7y agoNice way in without walrus m = re.match(p1, line) if m: return m.group(1) m = re.match(p2, line) if m: return m.group(2) m = re.match(p3, line) ... With walrus: if m := re.match(p1, line): return m.group(1) elif m := re.match(p2, line): return m.group(2) elif m := re.match(p3, line): The example would have been better if it didn't have the return, but just a value assign or a function call.
- singularity2001 7y agoDo parsers of previous pythons emit warnings: "this feature is not available in pythons 3.3 3.4 3.5 etc" ?
- deleted 7y ago[deleted]
- ben509 7y agoNo, just a SyntaxError. Generally, library authors won't be able to use it if they want to support many versions; same as with f-strings.
- lordnacho 7y agoGotta ask how many of these changes are actually reflective of changing environments. I could see with c++ that between 2003 and 2014 a fair few underlying machine things were changing and that needed addressing in the language. But Python is not quite as close to the machine, and I don't see how something like the walrus is helping much. If anything it seems like you'd scratch your head when you came across it. And for me at least one of the main attractions of python is you're hardly ever surprised by anything, things that are there do what you guessed, even if you hadn't heard of them. Function decorators for instance, you might never have seen one but when you did you knew what it was for. Same with the debug strings. That seems to be a special case of printing a string, why not leave it at that? I'm guessing a lot of people don't ever read a comprehensive python guide, what are they going to do when they see that?
- thaumasiotes 7y ago> I'm guessing a lot of people don't ever read a comprehensive python guide, what are they going to do when they see that? My guess would be "run it and see what it does".
- Waterluvian 7y agoThe lack of the "nursery" concept for asyncio really sucks. Originally I heard it was coming in 3.8. Right now asyncio has this horrible flaw where it's super easy to have errors within tasks pass silently. It's a pretty large foot gun.
- sametmax 7y agoYou can code your own wrapper for this. Like https://github.com/Tygs/ayo https://github.com/Tygs/ayo It's not as good as having it in the stdlib, because people can still call ensure_future and not await it, but it's a huge improvement and completly compatible with any asyncio code.
- Waterluvian 7y agoYup for sure. My complaint is part ergonomics of boilerplate, part this really burned me bad and no stdlib documentation warns you upfront about it. So many hours of headscratching.
- ProjectBarks 7y agoThe changes to f-strings just seems like a step in the wrong direction. Don't make the string content implicit!
- strictfp 7y agoAlso, why abandon printf-style? All languages tend to converge to printf over time, it's simply the most tried and tested model out there!
- baq 7y agohttps://pyformat.info/ https://pyformat.info/
- joshuamorton 7y agojavascript, python, rust, etc. don't use printf style, but instead use the {} style.
- strictfp 7y agoYeah, well Rust isn't exactly a success story in that regard if you ask me. A couple of weeks ago I tried to figure out how to format a float properly in Rust, and the way they made it work is a lot worse than straight up printf-style if you ask me.
- bvrmn 7y agoFormat string is very inconvenient approach because you need to duplicate type information. >>> '%i' % 's' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: %i format: a number is required, not str >>> '{}'.format('s') 's' >>> '{}'.format(10) '10'
- londons_explore 7y agoI long for a language which has a basic featureset, and then "freezes", and no longer adds any more language features. You may continue working on the standard library, optimizing, etc. Just no new language features. In my opinion, someone should be able to learn all of a language in a few days, including every corner case and oddity, and then understand any code. If new language features get added over time, eventually you get to the case where there are obscure features everyone has to look up every time they use them.
- plopz 7y agoIsn't that what C is?
- FPGAhacker 7y agoCertainly Common Lisp.
- hu3 7y agoFrom what I've seen, Go is the closest we have for mainstream language resistant to change.
- zubspace 7y agoRecently the Go team decided not to add the try-keyword to the language. I'm not a Go programmer and was a bit stumped by the decision until I saw a talk of Rob Pike regarding the fundamental principle of Go to stick to simplicity first. [1] One of the takeaways is, that most languages and their features converge to a point, where each language contains all the features of the other languages. C++, Java and C# are primary examples. At the same time complexity increases. Go is different, because of the simplicity first rule. It easens the burden on the programmer and on the maintainer. I think python would definitely profit from such a mindset. [1] https://www.youtube.com/watch?v=rFejpH_tAHM https://www.youtube.com/watch?v=rFejpH_tAHM
- nerdponx 7y agosomeone should be able to learn all of a language in a few days, including every corner case and oddity, and then understand any code. Why should this be true for every language? Certainly we should have languages like this. But not every language needs to be like this.
- RcouF1uZ4gsC 7y agoI find the different philosophies of languages amazing. Just recently 'Declined Proposal: A built-in Go error check function, “try”' https://news.ycombinator.com/item?id=20454966 https://news.ycombinator.com/item?id=20454966 made the front page, explaining how a controversial potential Go feature was being declined early. Python on the other hand, went ahead with what seems to be a proposal at least as controversial as 'try' in Go.
- preommr 7y ago":=" is a fairly common operator symbol that I've seen used in other programming languages (e.g. Golang) and in mathematics. But I've never seen it called the "walrus" operator. Its fitting and memorable though, I like it.
- nickthemagicman 7y agoIts kind of amazing to me switching from PHP/Ruby to Python, that things like f strings and walrus operators are just now being added to python.
- ggm 7y agoAnd the GIL...
- Animats 7y agoThe title made me think "Be afraid. Be very afraid". But it's all little stuff. Unchecked type annotations remain the worst addition since 3.0. Actual typing might be useful; it allows optimizations and checking. But something that's mostly a comment isn't that helpful.
- snicker7 7y agoBoth static checking and compilation can be implemented using third party libraries. I think projects like mypyc could be a real game-changer.
- joshuamorton 7y agoIf you don't like unchecked annotations, then check them. It's not hard to do.
- vesche 7y agoWas really hoping to see multi-core in 3.8, looks like we'll be waiting until 3.9 https://www.python.org/dev/peps/pep-0554/ https://www.python.org/dev/peps/pep-0554/ https://github.com/ericsnowcurrently/multi-core-python/wiki https://github.com/ericsnowcurrently/multi-core-python/wiki
- Stubb 7y agoA map() function that isn't just an iterated fork() would be glorious. Let me launch a thread team like in OpenMP to tackle map() calls containing SciPy routines and I'll be unreasonably happy.
- Areading314 7y agoVery much seems like perlification, and we all know what happened to Perl. Although that being said I always really liked Perl
- lizmat 7y agoPerhaps it's more Perl 6-ification?
- xaedes 7y agoWow. Never would I have guessed the amazing concept of assignment expression is so confusing for, what it seems, a lot of python programmers. It really was time to introduce it to them.
- jpetrucc 7y agoIt's not really that it's confusing, more so that it isn't necessarily 'pythonic'
- wil421 7y ago>Debug support for f-strings. F strings are pretty awesome. I’m coming from JavaScript and partially java background. JavaScript’s string concatenation can become too complex and I have difficulty with large strings. >Python 3.8 programmers will be able to do: print(f'{foo=} {bar=}') Pretty cool way to help with debugging. There are so many times, including today, I need to print or log some debug string. “Debug var1 ” + var1 + “ debug var2” + var2...and so on. Forgot a space again.
- joaolvcm 7y agoBy the way, this has nothing do with f strings but for debugging JavaScript you can do something like console.log({var1,var2,var3}); And the logged object will get created with the variables content and the variable nem as key, so it will get logged neatly like {var1: "this is var1", var2: 2, var3: "3"}
- kbd 7y agoDespite controversy, walrus operator is going to be like f-strings. Before: "Why do we need another way to..." After: "Hey this is great". People are wtf-ing a bit about the positional-only parameters, but I view that as just a consistency change. It's a way to write in pure Python something that was previously only possible to say using the C api.
- stefco_ 7y agof-strings are the first truly-pretty way to do string formatting in python, and the best thing is that they avoid all of the shortcomings of other interpolation syntaxes I've worked with. It's one of those magical features that just lets you do exactly what you want without putting any thought at all into it. Digression on the old way's shortcomings: Probably the most annoying thing about the old "format" syntax was for writing error messages with parameters dynamically formatted in. I've written ugly string literals for verbose, helpful error messages with the old syntax, and it was truly awful. The long length of calls to "format" is what screws up your indentation, which then screws up the literals (or forces you to spread them over 3x as many lines as you would otherwise). It was so bad that the format operator was more readable. If `str.dedent` was a thing it would be less annoying thanks to multi-line strings, but even that is just a kludge. A big part of the issue is whitespace/string concatenation, which, I know, can be fixed with an autoformatter [0]. Autoformatters are great for munging literals (and diff reduction/style enforcement), sure, but if you have to mung literals tens of times in a reasonably-written module, there's something very wrong with the feature that's forcing that behavior. So, again: f-strings have saved me a ton of tedium. [0] https://github.com/python/black https://github.com/python/black
- bulatb 7y ago> If `str.dedent` was a thing Have you looked at textwrap.dedent?
- stefco_ 7y agoYes! `textwrap.dedent` is great. On further reflection `wrap` is actually more useful for this kludge (see below). But my point is that that's a whole import for a kludge. Compare the f-string ideal (by my standards): raise ValueError("File exists, not uploading: " f"{filename} -> {bucket}, {key}") ...which is short enough that it's readable, and it's clear where exactly each variable is going. It's the single obvious solution, so much so that I don't spend a second thinking about it (very Pythonic!). Compare it to using `str.format` with the same continued indentation: raise ValueError(("File exists, not uploading: {filename} -> " "{bucket}, {key}").format(filename=filename, bucket=bucket, key=key)) Even this minimal example looks terrible! Remember that a lot of exceptions are raised within multiply-nested blocks, and then format pushes things farther to the right (while also ruining your automated string-literal concatenation, hence the extra parentheses), leaving very little room for the format arguments. You can use a more self-consistent and readable indentation strategy: raise ValueError( ( "File exists, not uploading: {filename} -> " "{bucket}, {key}" ).format(filename, bucket, key) ) This is unquestionably more pleasant to read than the former, but it's 3 times longer than the simple f-string solution, and I would argue it is not any more readable than the f-string for this simple example. My point with having a `str.wrap` builtin is that at least you could use the docstring convention of terminating multi-line strings on a newline, which would get rid of the string concatenation issues while leaving you a consistent (albeit diminished by the "wrap" call) amount of rightward room for the `format` args: raise ValueError("""File exists, not uploading: {filename} -> {bucket}, {key} """.dedent().format(filename=filename, bucket=bucket, key=key)) Maybe a little bit better than the first one, especially if you're writing a longer docstring and don't want to think about string concatenation. But still a kludge. You can use positional formatting to shorten things up, but the fundamental weakness of `str.format` remains.
- rcfox 7y agoI feel like I've been seeing a lot of these almost identical articles pop up all over. Walrus operator, f-string equals, positional-only arguments, yawn. None of that is really going to change your life. There's a bunch of changes in the official "what's new" doc that I think are more interesting: https://docs.python.org/3.8/whatsnew/3.8.html https://docs.python.org/3.8/whatsnew/3.8.html * Run-time audit hooks, to see if your modules are making network requests, etc. https://www.python.org/dev/peps/pep-0578/ https://www.python.org/dev/peps/pep-0578/ https://tirkarthi.github.io/programming/2019/05/23/pep-578-overview.html https://tirkarthi.github.io/programming/2019/05/23/pep-578-o... * multiprocessing SharedMemory for fast data sharing between processes https://docs.python.org/3.8/library/multiprocessing.shared_memory.html https://docs.python.org/3.8/library/multiprocessing.shared_m... * Duck-typing for the static annotation checkers https://www.python.org/dev/peps/pep-0544/ https://www.python.org/dev/peps/pep-0544/ * Literal checking for the static annotation checkers. ie: It's not enough to check that you're passing a string for the mode in open(), you want to check that it's 'r' or 'w', etc. https://www.python.org/dev/peps/pep-0586/ https://www.python.org/dev/peps/pep-0586/ * The compiler now produces a SyntaxWarning when identity checks (is and is not) are used with certain types of literals (e.g. strings, ints). These can often work by accident in CPython, but are not guaranteed by the language spec. The warning advises users to use equality tests (== and !=) instead. * A bunch of speed and memory optimizations: - "Sped-up field lookups in collections.namedtuple(). They are now more than two times faster, making them the fastest form of instance variable lookup in Python." - "The list constructor does not overallocate the internal item buffer if the input iterable has a known length (the input implements __len__). This makes the created list 12% smaller on average." - "Doubled the speed of class variable writes." - "Reduced an overhead of converting arguments passed to many builtin functions and methods. This sped up calling some simple builtin functions and methods up to 20–50%."
- stefco_ 7y agoThere's a lot of talk in this thread about Python going down-hill and becoming less obvious/simple. I rather like modern python, but I agree that some features (like async/await, whose implementation fractures functions and libraries into two colors [0]) seem like downgrades in "Pythonicity". That said, I think some things have unquestionably gotten more "Pythonic" with time, and the := operator is one of those. In contrast, this early Python feature (mentioned in an article [1] linked in the main one) strikes me as almost comically unfriendly to new programmers: > Python vowed to solve [the problem of accidentally assigning instead of comparing variables] in a different way. The original Python had a single "=" for both assignment and equality testing, as Tim Peters recently reminded him, but it used a different syntactic distinction to ensure that the C problem could not occur. If you're just learning to program and know nothing about the distinction between an expression and a statement, this is about as confusing as shell expansion (another context-dependent syntax). It's way too clever to be Pythonic. The new syntax, though it adds an extra symbol to learn, is at least 100% explicit. I'll add that := fixes something I truly hate: the lack of `do until` in Python, which strikes me as deeply un-Pythonic. Am I supposed to break out of `while True`? Am I supposed to set the variable before and at the tail of the loop (a great way to add subtle typos that will cause errors)? I think it also introduces a slippery slope to be encouraged to repeat yourself: if assigning the loop variable happens twice, you might decide to do something funny the 2:Nth time to avoid writing another loop, and that subtlety in loop variable assignment can be very easy to miss when reading code. There is no general solution I've seen to this prior to :=. Now, you can write something like `while line := f.readline()` and avoid repetition. I'm very happy to see this. [0] https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/ https://journal.stuffwithstuff.com/2015/02/01/what-color-is-... [1] https://lwn.net/Articles/757713/ https://lwn.net/Articles/757713/ [edit] fixed typos
- owlowlowls 7y ago>I'll add that := fixes something I truly hate: the lack of `do until` in Python, which strikes me as deeply un-Pythonic. Am I supposed to break out of `while True`? Am I supposed to set the variable before and at the tail of the loop (a great way to add subtle typos that won't cause errors)? This is relevant to what I've been doing in OpenCV with reading frames from videos! In tutorial examples on the web, you'll see exactly the sort of pattern that's outlined in the PEP 572 article. >line = f.readline() >while line: > ... # process line > line = f.readline() Just, replace readline() with readframe() and the like. So many off-by-one errors figuring out when exactly to break.
- dirkg 7y agoWhat Python needs is a better lambda syntax similar to JS and true anonymous multiline functions. Defining and using lambdas in Python feels very unpythonic, this is something JS gets perfectly. Also fix the GIL.
- patientplatypus 7y agoPersonally, I vote against the walrus. Code complication for a limited set of use cases. Boo, bad walrus.
- ihuman 7y agoHow come they are using a new := operator instead of using equals?
- dragonwriter 7y agoWhich equals? = (existing) is statement assignment == (existing) is expression equality := (new) is expression assignment
- ihuman 7y agoJust 1 equals. It could assign a statement to a variable, and return that value/variable to the if statement to check for truthyness a=42 if b = a: print(b) else: print("no") Would print "42". It works in C int a,b; a=42; if(b=a){ printf("%d\n",b); } else { printf("no\n"); }
- magicalhippo 7y agoIt works in C, and have caused countless bugs in C (and C++). So much so that many have adopted the rule that the variable goes on the right, "if 42 = b", to make sure the compiler barfs when you intended to write "if b == 42". With := it's less likely that mistake is made. I also find it visually more distinct, so easier to parse, but that might be very subjective.
- dragonwriter 7y agoThat works if “if” statements were the only place the assignment expression operator could be used. It works less well if they can be used everywhere an expression can occur, including the right side of assignments—especially since Python has both multiple (x = y, z) and chained (x = y = z) assignment, which can be used together. What does this mean if = is used for both assignment statements and assignment expressions: x = y, z = 10, 20 When they are distinct, these have different meaning: x = y, z = 10, 20 # x: (10, 20), y: 10, z: 20 x = y, z := 10, 20 # x: (<existing value of y>, (10, 20)), y: <unchanged>, z: (10, 20)
- andolanra 7y ago
- president 7y agoAnyone else think the walrus operator is just plain ugly? There is a certain aesthetic quality that I've always appreciated about the Python language and the walrus operator looks like something straight out of Perl or Shell.
- deleted 7y ago[deleted]
- BuckRogers 7y agoThe problem with modern Python is that it's trying to recreate C# or Java. Which leaves it with nothing, because it'll only end up an inferior version of the languages/platforms of which it's attempting to duplicate. When I was into Python, I liked it because it was a tighter, more to the basics language. Not having 4 ways to format strings and so forth. I don't think Python can defeat Java by becoming Java. It'll lose there due to multiple disadvantages. The way Python "wins" (as much as it could at least), is focusing on "less is more". They abandoned that a while ago. My vision of a language like Python would be only 1-way to do things, and in the event someone wants to add a 2nd way, a vote is taken. The syntax is changed, and the old bytecode interpreter handles old scripts, and scripts written with the latest interpreter's bytecode only allows the new syntax. For me that's the joy of Python. I think a lot of people wanted Python's original vision, "one way to do things". If I want feature soup, I'll use what I program in daily. Which I do want feature soup by the way, I just have no need to replace it with another "feature soup" language like Python turned into because it's inferior on technical and for me, stylistic levels.
- orangecat 7y agoMy vision of a language like Python would be only 1-way to do things, and in the event someone wants to add a 2nd way, a vote is taken. By that standard, the walrus operator is not only acceptable but essential. Right now there are at least 3 ways to process data from a non-iterator: # 1: loop condition obscures what you're actually testing while True: data = read_data() if not data: break process(data) # 2: 7 lines and a stray variable done = False while not done: data = read_data() if data: process(data) else: done = True # 3: duplicated read_data call data = read_data() while data: process(data) data = read_data() There's too many options here, and it's annoying for readers to have to parse the code and determine its actual purpose. Clearly we need to replace all of those with: while (data := read_data()): process(data) Yes, I'm being a bit snarky, but the point is that there is never just one way to do something. That's why the Zen of Python specifically says one "obvious" way, and the walrus operator creates an obvious way in several scenarios where none exist today.
- 7y ago
- ohazi 7y agoAlso type hints for dictionaries with fixed keys: https://www.python.org/dev/peps/pep-0589/ https://www.python.org/dev/peps/pep-0589/ I know it's almost always better to use objects for this, but tons of code still uses dictionaries as pseudo-objects. This should make bug hunting a lot easier.
- lxmcneill 7y agoHuh, was totally unaware of this. For me this has good implications for ingesting CSVs/.xlsx to dicts. Clean-ups / type hinting is required at times for dirtier documents.
- ben509 7y agoOh, nice! I'll have to add that to json-syntax.[1] [1]: https://pypi.org/project/json-syntax/ https://pypi.org/project/json-syntax/
- outerspace 7y agoDoes it make sense to use := everywhere (can it be used everywhere?) instead of just in conditionals? Just like Pascal.
- DonHopkins 7y agoAbout as much sense as it makes to use ; after every Python statement. Just like Pascal. (Yeah I know, ; is a statement separator, not a statement terminator in Pascal.) As long as you're being just like Pascal, did you know Python supported Pascal-like "BEGIN" and "END" statements? You just have to prefix them with the "#" character (and indent the code inside them correctly, of course). ;) if x < 10: # BEGIN print "foo" # END
- ben509 7y agoIt's not valid in an assignment statement, so you can't use it everywhere. FWIW, I agree with the sentiment; I use := for assignment in my language precisely because that's the correct symbol. But even there, my grammar accepts = as assignment as well because I type it from habit.
- apalmer 7y ago3
- apalmer 7y ago3r
- apalmer 7y ago2nd 2
- tasubotadas 7y agoI'll just put a reminder here that it's the year 2019 and AMD and Intel has 10-core CPUs while Python is still stuck with GIL ¯\_(ツ)_/¯
- ben509 7y agoIt's the current year! This is slated for 3.9: https://www.python.org/dev/peps/pep-0554/ https://www.python.org/dev/peps/pep-0554/
- tasubotadas 7y agoI think we both know that it's a poor substitute for proper threading.
- deleted 7y ago[deleted]
- Myrmornis 7y agoI believe that I hit places where I'd use the walrus about once every few hundred lines of python, so I do see a use for it. OTOH I am worried that it makes the language harder to understand for beginners, and that is a very important role Python plays in the world of programming languages. The abbreviated f-string syntax looks weird and kinda wrong to me. But then I'm not even sure I've got comfortable yet with the object field initialization shortcuts in Javascript and Rust (where you also get to omit stuff to avoid repeating yourself).
- musicale 7y agoAll I care about is allowing a print statement in addition to the print function. There's no technical reason why both can't coexist in a perfectly usable manner.
- mixmastamyk 7y agoTry an editor snippet like I did years ago. It's even shorter to type: pr<TAB> --> print(" ") # ^ cursor
- terminalhealth 7y agotl;dr: Computation is being compressed ever more
- sandGorgon 7y agoDoes anyone know the status of pep-582 : https://www.python.org/dev/peps/pep-0582/ https://www.python.org/dev/peps/pep-0582/ It's still marked as a 3.8 target
- mixmastamyk 7y agoToo late I think.
- jpetrucc 7y agoI love the f-strings and the new enhancements, but I'm still skeptical about the walrus operator and the positional argument change.
- vkaku 7y agoThat walrus operator has given me exactly what I wanted from C. Although I'd have preferred: if val = expr():
- hyperion2010 7y agoThat particular version opens the way for massive typo footguns and results in the insanity of defensive programming patterns like yoda expressions.
- vkaku 7y agoWell, for those used to those expressions, it definitely helps write that code with one line lesser (assignment by itself). Most likely, the assigned value is stored for use in one of the conditionals, so it really doesn't change any of that. Let's also understand that we are dealing with a decorated assignment here, so a = (b = c) should be no different from evaluating (b = c). It's not complicated, the way I at least look at it.
- vkaku 7y agoBut now I see your point. A language must not give beginners an option to shoot themselves in the foot.
- punnerud 7y agoIs there anything similar to BabelJS for Python? Now after 3.8 I start to feel there are a need for a tool like that. More compact code at the cost of higher learning curve.
- raymondh 7y agoTo me, the headline feature for Python 3.8 is shared memory for multiprocessing (contributed by Davin Potts). Some kinds of data can be passed back and forth between processes with near zero overhead (no pickling, sockets, or unpickling). This significantly improves Python's story for taking advantage of multiple cores.
- aportnoy 7y agoI’ve been waiting for this for a very long time. Thank you for mentioning this. Would this work with e.g. large NumPy arrays? (and this is Raymond Hettinger himself, wow)
- aidos 7y agoOh no way. That has huge potential. What are the limitations?
- acqq 7y agoFor us who didn't follow: "multiprocessing.shared_memory — Provides shared memory for direct access across processes" https://docs.python.org/3.9/library/multiprocessing.shared_memory.html https://docs.python.org/3.9/library/multiprocessing.shared_m... And it has the example which "demonstrates a practical use of the SharedMemory class with NumPy arrays, accessing the same numpy.ndarray from two distinct Python shells." Also, SharedMemory "Creates a new shared memory block or attaches to an existing shared memory block. Each shared memory block is assigned a unique name. In this way, one process can create a shared memory block with a particular name and a different process can attach to that same shared memory block using that same name. As a resource for sharing data across processes, shared memory blocks may outlive the original process that created them. When one process no longer needs access to a shared memory block that might still be needed by other processes, the close() method should be called. When a shared memory block is no longer needed by any process, the unlink() method should be called to ensure proper cleanup." Really nice.
- stesch 7y agoNo new way to format a string?
- stuaxo 7y agoIt seems like the PEP0505 for None aware operator is delayed indefinitely. It would be great if there was more momentum on this again, as it would be helpful in all sorts of places. https://www.python.org/dev/peps/pep-0505/ https://www.python.org/dev/peps/pep-0505/
- Grue3 7y ago>Python 3.8 programmers will be able to do: print(f'{foo=} {bar=}') Ugh, how did this get approved? It's such a bizarre use case, and debugging by print should be discouraged anyway. Why not something like debug_print(foo, bar) instead (because foo and bar are real variables, not strings)?
- jimktrains2 7y agoI don't understand why you think print or log debugging is inherently bad. Also, it's part of the format string and not a special print function so that it can be used for logs and other output as well, not just the console.
- Grue3 7y ago>I don't understand why you think print or log debugging is inherently bad. I use it myself all the time, but it just shows the weakness of the tooling that people have to resort to such measures. Fortunately, some people are working on it [1]. >Also, it's part of the format string and not a special print function so that it can be used for logs and other output as well, not just the console. Since print (and hypothetical debug_print) are no longer statements like in 2.x, there's nothing preventing them from returning the string that's supposed to be printed. For example print's keyword file is sys.stdout by default. Why not borrow from Common Lisp's format and make it return the string if file=None is passed? Then you could do logging.warning(debug_print('Unusual situation', foo, bar, file=None)) and it would print "WARNING: Unusual situation: foo=foo_value, bar=bar_value" to the logs. It's so much clearer. [1] https://github.com/cool-RR/pysnooper https://github.com/cool-RR/pysnooper
- jimktrains2 7y ago> I use it myself all the time, but it just shows the weakness of the tooling that people have to resort to such measures. It's not resorting to anything. It's a valid means of debugging. People use it even in languages like c and Java and in-browser JavaScript with very capable debuggers. It's quick, simple, and doesn't require intervention to record or examine anything. > Why not borrow from Common Lisp's format and make it return the string if file=None is passed? Because thatsa terrible idea because it's non-intuitive, verbose, and potentially confusing. Debug format strings are common in other languages, such as rust, so this isn't some half-thoughtout, python-only idea.
- atiredturte 7y agoI feel like walrus operators, while a cool construct, are at odds with "The Zen of Python". Specifically "There should be one -- and preferably only one --obvious way to do it." If this was any other language, the addition would be welcome, but I feel that the walrus operator fundamentally disagrees with what python is about. It's not about terseness and cleverness, it's about being clear, and having one way to do things (Unless you are Dutch). https://www.python.org/dev/peps/pep-0020/ https://www.python.org/dev/peps/pep-0020/
- mcdermott 7y agoPython has "jumped the shark" for me. Python is no longer Pythonic (the "import this", zen of python easter egg should be removed). It's lost it way and is TIMTOWTDI now, heading for that Perl 6 brass ring. Golang is now the Pythonic language.
- RocketSyntax 7y agoIsn't the walrus just like a case statement?
- antpls 7y agoAt first, after reading the comments and before reading the article, I thought everyone was just casually bashing because of change. But just look at this : def fun(a, b, /, c, d, *, e, f): or print(f'{now=} {now=!s}') and guess what it does before actually reading the article. Worst, the rationales of the PEPs are weak, presenting improvement for "performances" or enforcement of API because of low level stuff as C. Back when I was 18 years old, Python was high level, rules were simple with only one way of doing things and performances weren't a concern, because you would just use the right language for the right task. There was no enforcement and you could always hack a library to your liking. Python now is getting closer to what Perl looked to me 10 years ago, trying to optimize stuff it shouldn't