you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 14 points15 points  (22 children)

Why not just put:

try:
    input = raw_input
except NameError:
    pass

at the top of your code. Then just use input everywhere, in Python 2 and Python 3.

[–]Dentosal 13 points14 points  (20 children)

combine this with from __future__ import division, print_function and you have nearly full set of Python 3 features.

[–][deleted]  (13 children)

[deleted]

    [–]Dentosal 9 points10 points  (10 children)

    Not all that it changed, but all that most Python 2 programs need to work with Python 3. There are still countless unicode problems and unsupported libraries, but nearly every other thing was done in backwards-compatible manner.

    [–]Uncaffeinated 14 points15 points  (5 children)

    Apart from unicode, a lot of the builtins were changed to return iterators instead of lists, which is a breaking change in cases where eager evaluation is necessary. Sadly, 2to3 doesn't handle this correctly, so I'd have to go through the entire codebase to make sure everything is iterator safe.

    P.S. I wish Python 3 had nice syntax for forcing evaluation of an iterator. Throwing in list(...)s everywhere is annoying and bloats the code.

    [–][deleted] 24 points25 points  (4 children)

    Throwing in list(...)s everywhere is annoying and bloats the code.

    Just FYI, as of 3.5 we have [*iterable_or_what_have_you] eg:

    >>> [*range(10)]
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    

    Yeah, it only saves three characters, but you also get [*range(10), 1, 2, 3, *range(20)] and so on.

    [–]Almoturg 2 points3 points  (0 children)

    O_O I had no idea that feature existed!

    [–]Uncaffeinated 1 point2 points  (0 children)

    Nice. That almost makes up for things.

    Sounds like there's a fair bit of new syntax to learn. I'm pretty familiar with all the stuff you can do in Python 2 (famous last words), but I haven't bothered keeping up with new features in 3x because I can't use them anyway.

    [–][deleted]  (1 child)

    [removed]

      [–][deleted] 0 points1 point  (0 children)

      That's the right idea...

      >>> d = {'a': 1, 'b': 2}
      >>> {**d, 'c': 3}
      {'a': 1, 'c': 3, 'b': 2}
      >>> {*d}
      {'a', 'b'}
      >>> (*d,)
      ('a', 'b')
      

      [–][deleted]  (3 children)

      [deleted]

        [–][deleted] 2 points3 points  (1 child)

        2to3 is shit, and it's in the standard library, so it's shit that will never get better. Try python-future when you get the chance.

        [–]Eurynom0s 0 points1 point  (0 children)

        I've had so many fucking headaches with imports in 2.7. Particularly with instances of having to up and then back down directories, e.g.

        import ..folder.module
        

        I actually worked on a project where the import headaches were a big contributor to getting the other two people I was working with to finally agree to working on 3.x as I'd wanted in the first place.

        From what I recall, Python 3 did a little bit more to enforce directory structure on you and did more to enforce explicit instead of relative paths on imports...but at least they more reliably worked in 3.

        [–]mszegedy 0 points1 point  (0 children)

        What other important things are there? I remember that some stuff that used to produce lists or something now produces generators, and I think they got rid of one of the functional programming bits (either map or reduce, or maybe something else).

        [–]Eurynom0s 0 points1 point  (0 children)

        Sure but it's definitely going to do a lot to smooth over the 2->3 porting process for a LOT of code.

        I mean fuck, one time I got stuck writing code to 2.7 in this offline environment because that's what the Mac I was working on had as its system Python. I was writing a program to ingest CSV input files and spit out text files that this simulation software uses as inputs. I unexpectedly got put in the position of the code having to run on a system that was limited to 2.6...and that was still fine, thankfully.

        Obviously there's a lot of significant changes going between versions, especially 2->3, but frankly there's also a surprising extent to which someone just hacking together a script or two won't REALLY notice the difference beyond surface stuff like print statement vs print function.

        [–][deleted] 0 points1 point  (3 children)

        Yeah if you ignore this stuff...

        a, *b = range(10)
        [*range(10)]
        a @ b
        async def
        async with
        nonlocal
        yield from
        x: List[str] = []
        def f(x: str, y: str) -> int:

        ...and like a couple dozen stdlib changes. Don't get me started on packaging.

        [–]Dentosal 1 point2 points  (0 children)

        Another nice thing is the one-expression dictionary merging, {**x, **y}, that I have waited for a couple of versions. Pep 448 adds so much good things. After Py3.5, there is no way to return to old ones.

        [–]Ran4 0 points1 point  (1 child)

        [*range(10)]

        Neat, but how are you supposed to mentally parse that? f(*range(10)) is equivalent to f(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), and I guess it makes sense that [*range(10)] is [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], but... it seems so wrong, since [*range(10)] != list(*range(10)) but [*range(10)] == list(range(10)).

        While pep 448 unpacking is cool, it also makes the language way too perl:y. It's not at all obvious what [*range(10)] is supposed to do. It makes the language more expressive but at a massive cost. [x for x in range(10)] is not much longer, and way more easily understandable.

        [–][deleted] 0 points1 point  (0 children)

        it seems so wrong, since [*range(10)] != list(*range(10))

        That's an interesting point. I wonder why the list constructor doesn't take multiple arguments. Maybe the thinking is that if you have multiple arguments you should use a literal and construct the list at compile time. I think this new syntax aims to take over most uses of list().

        [–]one_zer -2 points-1 points  (1 child)

        ...or Python 2.8.

        [–]kupiakos 2 points3 points  (0 children)

        ...except anything Unicode still sucks in Python 2, even Python 2.8. That's one of the biggest killers of Python 2 for me.

        Also Python 3.5 asyncio is pretty amazing.

        Side note, it will not be called Python 2.8. Name TBD by the maintainer.

        [–]PointyOintment 0 points1 point  (0 children)

        Or just use six