Python 3.5.0
python.org
python.org
If your codebase is large, it can feel daunting, but it's not usually that bad.
Although, I still find myself running tests and cursing at the fact that I keep writing print "string" without the brackets :D
Using it you can safely cleanup/commit transaction/release lock/etc when exiting a block of statements (even if an exception was raised). Plain 'with' statement cannot call asynchronous code in '__exit__' methods, 'async with' can do that (in '__aexit__').
I was under the impression that type checking was not one of the goals of PEP 484 etc.
In C#, the using statement combines with async/await. It is cool that Python finally gains proper async/await, there is no need to diss other languages.
An edge over what? You're still limited to a single thread via the GIL. Until that problem is solved, Python is certainly not the best bet (all else aside) for server development.
Do you really need to share mutable state between threads in your server? If yes, what's your story when you'll need to scale to multiple servers?
If not because you can keep shared mutable state in a separate service (DB or similar), you can deal with one-machine scaling very similarly to scaling across machines - just start/fork a process per CPU. You get simplicity, avoid the whole thread-safety can of bugs, and all the administration benefits of stateless servers.
You mean, second gear up to fifth?
I tried writing some Python 3 code and the lack of parameter tuple unpacking by itself stunned me and drove me crazy, never mind other stuff. Python 3 seems very user-unfriendly compared to Python 2. Won't touch it with a ten foot pole unless my life depends on it.
def fxn(a, (b, c), d):
pass
Be a valid function signature. So the destructuring is held in the function definition.Python 3 will still allow
def fxn(a, x, d):
(b, c) = x
pass
Both Python and ES6 JavaScript allow destructuring arrays://javascript
let [x, y] = [1,2]
#python
[x, y] = [1,2]
(x, y) = (1,2)
function fxn(a, [b, c], d) {
console.log(a, b, c, d);
}Uh, thanks?
I would call it anything but "rightful". Making life harder for introspection tools is hardly a rightful reason for removing a core language feature. The code is what most developers are trying to develop, not the introspection tools.
Well that's one reason yes, and by itself not really a good enough one. But if you read the PEP there are another 4 good reasons that you omitted from your comment, why is that?
Because the other reasons were twice as horrible.
"No loss of abilities"? Uh, you can't do this in lambdas anymore.
"Exception to the rule"? Who cares? It was useful and readable, that's all that matters.
"Uninformative Error Messages"? This has never been a pain point for me. If you don't like it then no one forced you to use it...
"Little Usage"? Well I guess everyone matters but me. Which is fine, but then you shouldn't wonder why it would tick me off.
I don't mean to sound like I'm trying to belittle your position, I would like to understand more. The PEP below doesn't seem to do a very good job explaining why people like them, and I'd like to hear a proponents position on the feature.
Unless I'm missing something, I don't see this as a show stopper personally, and see it as increasing readability.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
> I don't mean to sound like I'm trying to belittle your position, I would like to understand more. The PEP below doesn't seem to do a very good job explaining why people like them, and I'd like to hear a proponents position on the feature.
Basically, I need it for functional programming. See here:
What are the cases where you use it / rely on it?
Basically any time I need to unpack inside a lambda (e.g. functional programming) and have to use something like itertools.groupby(), I run into trouble with Python 3. For example:
from itertools import groupby
def groupby_unsorted(items, key):
return map(lambda (g, l): (g, map(lambda (k, v): v, l)), groupby(sorted(map(lambda v: (key(v), v), items)), lambda (k, v): k))
print(groupby_unsorted([1, 2, 3, 4], lambda v: v % 2))
Never ran into problems with it either. def groupby_unsorted(iterable, key):
return [(k, [v for k, v in g])
for k, g in
groupby(sorted((key(v), v) for v in iterable),
lambda item: item[0])]
print(groupby_unsorted([1, 2, 3, 4], lambda v: v % 2))The point was that writing something like
lambda item: item[0]
in your code is inferior to lambda (k, v): k
in terms of readability and comprehensibility. It is both longer and it also doesn't document the fact that the item is semantically a key-value pair.The problem is not (and has never been) whether something is "necessary" or "possible". Tuple unpacking obviously completely unnecessary to begin with, it has nothing to do with whether this is done in a parameter or not. The problem is whether the code is expressed better via unpacking.
The other features are all well rounded, with co-routines having quite some potential, though I'd have to play around with them first to assess.
Now if everything would please start moving on to Python 3 pretty please ;).
The optional typing is a tricky subject. I'll have to wait until there are tools actually using it to see. One of my biggest hesitances with it is that until runtime checking or really good static analysis exists, annotating things incorrectly can be too easy. I am cautiously optimistic though. The theory is fantastic, just have to wait for the follow through. The best way to sort-of statically type things right now(imo) is through namedtuples (which I make use of heavily for lightweight, strict datatypes)
Formatting for bytes and bytearray is actually one I run into a ton trying to port py2 code to py3. Pretty excited about that.
I tried hard to think of ways to (ab)use '@', and this XML example and perhaps some sort of messaging API were the only two I could come up with where there was a natural domain-specific mapping.
One of the advantages of keeping '@' at the same precedence level and ordering as '*', '/', '%', and '//' is that it doesn't really offer much in the way of new use. If someone uses '@' for something very unlike matrix multiplication, then they could already use any of the other 4 symbols that way.
So I don't think @ ends up as an attractive nuisance.
If you mean node[x] returns node.attrib.get(x) when x is a string, and the nth-child when x is an integer, then I think that puts too much complexity into the API.
If you mean stay with the existing node.attrib dict-like API, then node@name is a simple shortcut for node.attrib.get(name), but it's 1) more aligned with CSS/XSL '@' notation for attribute syntax, and 2) faster in CPython.
(Just realized that '/' and '//' also make sense in that context. node / "abc" / "xyz" @ "p" would be the child "abc"'s child "xyz"'s attribute "p". Perhaps my proposal is a bad idea because it might suggest that these other forms are allowed.)
The matrix multiplication PEP is actually titled "A dedicated infix operator for matrix multiplication", and that's (broadly) the only thing that it provides. Here's the arguments for why the operator should exist: https://www.python.org/dev/peps/pep-0465/#why-should-matrix-...
numpy and other libraries might/has/will implement the matrix multiplication infix operator for their array and matrix data types.
http://legacy.python.org/dev/peps/pep-0465/#id24
Implementing __matmul__, __rmatmul__ and __imatmul__ will allow you to apply this operator to any given class. In that light, you could subclass the numpy matrix class yourself and simply apply these.
As for whether these will be applied to Python lists, my speculation is: I doubt it. Its possibly the most commonly used data structure, and I doubt they would add the overhead of another set of methods on each instance.
It wouldn't incur any overhead, don't know why you'd think it would. Each method of any object only needs to be stored once, not again for every instance. The overhead comes from pointers and data fields such as the length.
Unless I'm grossly mistaken, Python methods add basically no per-instance overhead (they add per-class overhead.)
Looking forward to this as well. So far the only static analysis tool I'm aware of that makes use of the PEP 484 framework is mypy [1] -- does anybody happen to know of other tools in the works?
Feels like such a step back when I have to use a Python 2.x codebase - so many little annoyances.
I made python 3 a 'production readiness requirement' at the start of this year.
My two biggest Python3 complaints have stopped being 'something doesn't work' to 1: Pyston is targeting Python 2 and 2: PyPy doesn't care enough about Python 3 ( I mean seriously... PyPy + AsyncIO = EPIC )
Unfortunately, not always an option. Or rather, it is, but would require an immense amount of effort. Not to mention, the client wouldn't be too happy with the increase in bugs.
Working on a legacy C++/Python implementation stuck with 2.5. It's not as bad as it sounds, really. You learn to improvise, and work on python 2.7/3+ in off-hours.
I thought that Python3 removed 'u' strings, was this just a bit of humour in the PEP?
https://www.python.org/dev/peps/pep-0448/ https://www.python.org/dev/peps/pep-3132/
I'd be really nice to use this.
>>> [*range(i) for i in range(5)]
Instead of this monstrosity right now. >>> [x for y in (range(i) for i in range(5)) for x in y]
Python 2.7 has some minor features that 3 dropped unfortunately, which still makes me hesitate.Such as filter keeping the type. In 3 it returns an iterator.
>>> filter(lambda x: x in 'ABC', 'ABCDEFA')
'ABCA'
Or this mostly cosmetic feature. >>> filter(lambda x: x[0] > x[1], ((1, 2), (4, 3)))
>>> filter(lambda (x, y): x > y, ((1, 2), (4, 3))) # equivalent, error in 3
Also dropped. (It's slower than using the dedicated base64 module though.) >>>'Python'.encode('base64')
'UHl0aG9u\n'
Also, I like print. >>> sum((range(i) for i in range(5)), [])
[0, 0, 1, 0, 1, 2, 0, 1, 2, 3]
and >>> import itertools
>>> list(itertools.chain.from_iterable(range(i) for i in range(5)))
[0, 0, 1, 0, 1, 2, 0, 1, 2, 3]
"filter keeping the type". That was only true for some types. Python 2.7's filter does not maintain the set type: >>> filter(lambda x: x in 'ABC', {'A','B','C','D','E','F','A'})
['A', 'C', 'B']
Regarding the cosmetic feature, that's a consequence of PEP 3113 -- Removal of Tuple Parameter Unpacking , https://www.python.org/dev/peps/pep-3113/ , which also applies to functions.I use 's.encode("hex")' often. I realize why hex/base64 are gone, but it's so short and easy in Python 2.7.
This won't work in Python 3 since `range` is a new type (and it's O(n²) anyway, so not missed).
The second option is idiomatic IMHO.
>>> for i in range(20):
... t1 = time.time()
... n = len(sum((list(range(i)) for i in range(2**i)), []))
... t2 = time.time()
... print(i, t2-t1)
...
0 0.00010800361633300781
1 2.288818359375e-05
2 2.5033950805664062e-05
3 4.00543212890625e-05
4 7.295608520507812e-05
5 0.00017499923706054688
6 0.0005929470062255859
7 0.0024929046630859375
8 0.012469053268432617
9 0.14577507972717285
10 1.7278220653533936
11 17.82376503944397
^C
(MHO too, BTW.)> >>> filter(lambda x: x in 'ABC', 'ABCDEFA') > 'ABCA'
it was a special case for a few types, didn't (couldn't) work for all types e.g.
>>> filter(lambda x: x in 'ABC', set('ABC'))
['A', 'C', 'B']
> Also, I like print.I like Python 3's print. It's kind-of a pain because my day-to-day uses Python 2 and the context switch is annoying, but 3's is way more flexible and readable:
print <<f, foo, bar # (or is it >>file? I can never remember)
versus actually makes sense, no sigil soup
||
\/
print(foo, bar, file=f, flush=True)
/\
||
separate statement necessary in P2
and because it's an expression it can be used in more context than Python 2's print statement.I feel you on the loss of argument unpacking, it was a very convenient feature (though not too common IME)
>>> from __future__ import print_function
>>> print("hi")
hi
>>>
My team is starting to use it as we look to migrate various command line utilities to python 3. >>> [x for y in (range(i) for i in range(5)) for x in y]
can be simplified into: [y for x in range(5) for y in range(x)] [*range(i) for i in range(5)]
and {**d for d in ds}
but it was removed ultimately because people in dev-python found it confusing. If you're interested in seeing that construction in Python, I suggest waiting until 3.5 gains some traction and then making a suggestion in python-ideas.FWIW, I'm the PEP writer. It's not my invention, I just wrote it up. It still makes me glad when people mention the PEP, though :).
That really bugged me for a while, but then I added a "snippet" into my editor. Now I type: pr then the tab-key, and it transforms to:
print('', ) # with cursor between quotes
and it works well, also I have similar shortcuts for logging. >>> codecs.encode(b'Python', 'base64')
b'UHl0aG9u\n'
The encodings still exist; hex works too (or hex_codec in older Python 3s). Python 3 just restricted the encode/decode methods to always go str to bytes or bytes to str.I'm constantly having to hack around bugs in ancient versions of libraries that have been fixed years ago for the same reason.
I have a feeling the slow adoption rate of python 3 is not due to developers "rejecting" it.
Point is, defense industry doesn't automatically equal a locked down environment.
I've written a number of scripts for data analysis and simulation in Python that are much more portable for us since we don't need to get a license to run MATLAB on computers out in the field.
If you're in the EE department...I had your exact same job a year ago. And your main Python users are down the hall in ACS. Those guys are great. Maybe EE has started to change some...since they lost pretty much half the department. For your sake, I hope so.
I have taken to using the 3 syntax in 2.7 so that I am prepared, but until this particular library moves, I cannot.
I've run into my fair share of Python 3 roadblocks, but you'd be surprised how far you can get by making a little noise and sending the occasional patch. Library authors are much more willing to prioritize Python 3 support if it looks like people actually need it :)
(I understand that adding os.scandir might require a PEP)
https://mail.python.org/pipermail/python-ideas/2012-November... is the original proposal on -ideas.
Flask, sqlalchemy ,etc seem to be using gevent and py 2.7.
https://github.com/klen/py-frameworks-bench/blob/develop/fra...
Right now, it seems to me that Python 3.5 is not ready for adoption since it is not usable with any framework at all. I mean, I really want to use asyncio, but 99% of python mindshare is around SqlAlchemy, Bottle, Flask, Django and Cherrypy. and I cant use it with any of them.
aiohttp looks cool, but I would much rather use one of the above for now. Anybody know why are none of these framework maintainers leveraging this stuff ?
It's hard to write an asynchronous ORM though. Your options are either to use some existing synchronous ORM (like SQLAlchemy) in a thread pool (`loop.run_in_executor`) or use more low-level db driver: https://github.com/aio-libs/aiopg#example-of-sqlalchemy-opti...
In fact if you look closely at the benchmark code (https://github.com/klen/py-frameworks-bench/blob/develop/fra...), the comparison is not against flask+gevent+psycogreen which may change the numbers.
[1] http://pythonhosted.org/pulsar/ [2] https://pypi.python.org/pypi/pulsar-odm
I've tried Python 3 and enjoy it very much. A few things drove me nuts at first, trying to figure out why syntax that worked in Python2 is not longer working in Python3. But a little bit of googling and I was on my way with Python3.
I have a project that I started a long time ago in Python2 using web.py. I tried to migrate to Python3, but unfortunately, web.py is not supported. I know Flask has python3 support and I could migrate to that but I'm not ready to move my whole code base over yet.
From someone who tried to migrate to Python3 with no compelling reason to, hit a roadblock, I immediately shelved the problem till later as I'm not missing anything critical from Python3 to warrant the effort.
I wonder how many other projects go through this? Especially much larger, more complex code bases.
Sadly the situation for using asyncio for web was not that great last I checked, because that would be a strong incentive.
P.S. That flask warning is definitely very out of date. I used Flask with Python3 quite happily, literally this week.
Also, pytest users might want to use their dev version for now until they fix a 3.5 issue.
In that case, `pyenv install 3.5.0` and then `pyenv shell 3.5.0` or `pyenv global 3.5.0` to switch which Python gets used. With pyenv's virtualenv plugin, you can also get rid of the need to use virtualenvwrapper for managing dependencies.
$ head -1 /usr/bin/lsb_release
#! /usr/bin/python3 -Es
Obviously, all utilities should do this, and should probably be more specific than that. Distros could have a tool to patch this automatically, and then they wouldn't break when the user chooses to upgrade system python.For stability it's best to keep the system managed through packages from the standard repositories. If you install things that are not from the repositories the packaging system won't be able to track dependencies - it will have bad information about some capabilities as some items won't have been installed using the packaging system. Overwriting official system libraries is a common cause of problems.
It's best to only upgrade something when the repository for your release makes it available: it pays to be conservative about the repositories you use, sticking to the standard ones and thinking very carefully about adding any others (e.g PPA's).
If you want 'newer' versions of frameworks/libraries for development then you're better off installing them away from the main system - traditionally that is /usr/local, or using a partitioning system such as chroot.
For Python specifically there's a really nice option of use venv/virtualenv.
* The new subprocess.run() function provides a streamlined way to run subprocesses.
Yeah! I've implemented that function a dozen times in projects, I suppose because it was too trivial to put on pypi.
* collections.OrderedDict is now implemented in C, which makes it 4 to 100 times faster.
Nice, I use this one relatively often.
def some_co():
yield 2
yield 3 It is a SyntaxError to have yield or yield from expressions in an async function.
That's what I mean when I say it misses the mark. There are now two ways of doing the same thing and one of them is more powerful than the other. Using generators I can use both `yield` and `yield from` but if I use what they're calling co-routines then I can only use `yield from`. I see no value in the new syntax.So an async function is not really a co-routine. It is a regular function that gets to use `await` and that's it. Calling it a co-routine is misleading and confusing.
But you don't return more than once from a coroutine. You can suspend it as often as you like, and that's what "await" does.
https://www.reddit.com/r/programming/comments/3k9yif/larry_w...
You do have a point, right? Coming in to a thread about a python release and trying to stir up controversy?
Or are you just doing it for kicks?
Hypothesis: distributions started installing python3 by default now, so people don't have to download it separately anymore. Python 2 downloads will stay at the same level as they were and actually 2.6 will go up as it's not available in supported distributions anymore. This is strangely opposite trend to actual adoption.