Although, I still find myself running tests and cursing at the fact that I keep writing print "string" without the brackets :D
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.
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.
What are the cases where you use it / rely on it?
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. [*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 :).
> >>> 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. >>> 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.
>>> [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)]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.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.
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.
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'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.
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 :)
P.S. That flask warning is definitely very out of date. I used Flask with Python3 quite happily, literally this week.
Sadly the situation for using asyncio for web was not that great last I checked, because that would be a strong incentive.
https://www.reddit.com/r/programming/comments/3k9yif/larry_w...
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.
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?
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.
$ 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.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.
(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.
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.
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.
Also, pytest users might want to use their dev version for now until they fix a 3.5 issue.
* 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.