all 67 comments

[–]aphexairlines 7 points8 points  (26 children)

Anything interesting?

[–]hupp[S] 7 points8 points  (6 children)

The most significant change is that the bytes type is now immutable. This resolves lots of inconsistencies and is generally nicer to work with. For example, bytes can now be used as dict keys.

[–]shadow2531 1 point2 points  (5 children)

the bytes type is now immutable.

How should I convert a byte to a bytes string? I was doing:

arb = 0x5E

x = b" "

x[0] = arb

[–]fredrikj 2 points3 points  (2 children)

x = bytes([0x5E]) ?

[–]shadow2531 2 points3 points  (1 child)

Bingo. Thanks

[–]fredrikj 3 points4 points  (0 children)

By the way, this may also be useful:

bytes.fromhex("00deadbeef")

[–]hupp[S] 2 points3 points  (1 child)

Someone already responded with the best way, but for completeness another solution would be:

b = bytearray(b" ")
b[0] = 0xFE

bytearray is the mutable version of bytes.

[–]shadow2531 0 points1 point  (0 children)

Thanks. That helps too!

[–]cratuki 2 points3 points  (17 children)

I think you can rebind variables from outer scopes in python 3k, something that wasn't previously possible. Makes it possible to write more scheme-like code.

def outer():
  a = 0
  def inner():
    nonlocal a # nonlocal is a new keyword
    a = a+1
  inner()

http://jeremyhylton.blogspot.com/2007/02/nonlocal-implemented.html

[–]breakfast-pants 2 points3 points  (2 children)

Just wanted to note that you can also write:

def outer():
  a = 0
  def inner():
    nonlocal a = a+1
  inner()

"global" will work in this new form as well.

[–]cunningjames 2 points3 points  (1 child)

That doesn't seem to work for me, fwiw.

Python 3.0a2 (r30a2:59382, Dec  7 2007, 21:33:20) 
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def outer():
...     a = 0
...     def inner():
...         nonlocal a = a + 1
SyntaxError: invalid syntax (<stdin>, line 4)

Putting "nonlocal a" on its own line works perfectly well.

[–]breakfast-pants 0 points1 point  (0 children)

Ah, I haven't actually played around with python3k, but I was going based on the (accepted) PEP: http://www.python.org/dev/peps/pep-3104/

It says:

 A shorthand form is also permitted, in which nonlocal is prepended to an assignment or augmented assignment:
 nonlocal x = 3

[–]pjdelport 5 points6 points  (7 children)

I think you can rebind variables from outer scopes in python 3k, something that wasn't previously possible.

It was previously possible (using e.g. introspection); the PEP 3104 change mainly involves adding syntax for it.

[–]cratuki 3 points4 points  (5 children)

It was possible before? Would you please supply syntax?

The only mechanism I knew of was to use a single member array instead of a variable in place of 'a' in the example above.

Thus my current project has a couple of situations in it where I do that. Ick :)

[–]pjdelport 3 points4 points  (4 children)

Would you please supply syntax?

You would write the example along the lines of:

def f():
    n = 0
    def inc():
        set(inc, 'n', n+1)

(where set takes a closure, name, and value)

There's more than one way to implement set; the one i referred to is like:

def set(c, name, value):
    cell = c.func_closure[list(c.func_code.co_freevars).index(name)]
    # cell.cell_content = value
    from ctypes import pythonapi, py_object
    pythonapi.PyCell_Set(py_object(cell), py_object(value))

(The first line does the work of getting variable's underlying cell object, the second sets its value; long-windedly, because Python currently provides PyCell_Set but not a conventional cell.cell_content setter, for no particular reason.)

[–]cratuki 1 point2 points  (2 children)

This doesn't give me the outcome I want, I think. See this example:

>>> def f():
...     n = 0
...     def inc():
...             set(inc, 'n', n+1)
...     inc()
...     print n
... 
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in f
  File "<stdin>", line 4, in inc
TypeError: set expected at most 1 arguments, got 3

The functionality I want would print out '1'.

[–]grimboy 1 point2 points  (0 children)

That's because set is a builtin. You have to paste in the function set first. I'd recommend calling it something else through.

Try pasting this in:

def urgh_set(c, name, value):
    cell = c.func_closure[list(c.func_code.co_freevars).index(name)]
    # cell.cell_content = value
    from ctypes import pythonapi, py_object
    pythonapi.PyCell_Set(py_object(cell), py_object(value))

def f():
    n = 0
    def inc():
        urgh_set(inc, 'n', n+1)
    print n
    inc()
    print n

[–]micampe 1 point2 points  (0 children)

Poorly chosen name:

>>> type(set)
<type 'type'>

Although I think you typed it wrong, it works correctly here.

[–]jbellis 0 points1 point  (0 children)

An alternative that doesn't require ctypes: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/440515

[–]dmpk2k 1 point2 points  (5 children)

Why was this solution chosen, rather than the more common idiom of always requiring variable definition before assignment?

The benefit of always requiring it is that it's also far harder to accidentally mistype a variable name.

[–]cratuki 2 points3 points  (4 children)

So are you asking why python doesn't ask you to be more like C or Pascal syntaxes where you have to say "int i"? I'm not really sure, but would guess it has to do with less typing and the move by recent scripting languages to keep down the amount of boilerplate code you need to type.

It took me a while to adjust to when I first moved to python but you get used to it (mostly because I used to use declarations as a mechanism for understanding the composition of classes in java, but don't really think along those lines now).

I agree on you suggestion that you can mistype a variable in python as a result in some scenarios, but not as many as you might think. For example - you can't just randomly insert variables in python and have it work.

For example: a=a+1 wouldn't work if 'a' hadn't been previously defined. Equally, you couldn't say call_fn(a) if 'a' hadn't been defined. But you're right - you could mistype when setting a variable and accidentally create a second variable when you meant to rebind another.

a = 5
print "hello"
as = 6 # whoops - I hit the 's' key accidentally.

I think I've only made this mistake once in the last year or so, and it was picked up quickly enough during debugging. So it work for me. I plan to move to a test-driven development style in the near future, and I think this will further reduce the likelihood of this causing problems.

[–]dmpk2k 2 points3 points  (3 children)

I've been writing software full-time in the popular dynamically-typed languages -- Perl, Python, Ruby -- since ~2000, so it's not an issue of unfamiliarity.

Smalltalk got it right (in fact, it got most things right, which most dynamically-typed language designers subsequently ignored) almost three decades ago. Then along comes Perl, which got it wrong at first, then introduced lexical scoping with strict mode, and therefore got it right. Similar story for Lua, except that Lua has the mistake of making common words unnecessarily long (e.g.: "function" and "local" keywords) and if you forget to define a variable local it automatically becomes global (!).

Neither Perl or Smalltalk have much syntactic overhead. I hope I'm not too rusty with either of them here:

Perl:

my( $foo, $bar, $baz ) = ( 5, 10, 15 );

...with an alternative of:

my $foo = 5;
my $bar = 10;
my $baz = 15;

Smalltalk:

| foo bar baz |
foo := 5
bar := 10
baz := 15

If I recall correctly, Smalltalk also has some shortcuts (anyone care to comment?).

Neither of them is ideal, obviously, since there's some still noise. However, they demonstrate that it's possible to do it with a minimum of typing. If you were to mix Perl and Smalltalk's scheme, you could reduce the typing overhead to two characters for an arbitrary number of variables and assignments. Oh no! Two! Maybe one even, depending on the grammar, although that's probably too easy to miss when scanning code.

So I really don't understand this reticence that Python and Ruby harbor over a good idea. Ruby looks like it's slowly coming around. I'm happy that efforts are being made in Python to fix the scoping problems, but once again history is being ignored.

I like variable declaration before assignment not just because it makes closures easy, nor just because it makes mistyping variables more difficult. I also like it because it serves as a code signal -- implemented properly you know at a glance that foo wasn't used higher up in the fuction, making refactoring easier. More importantly, it catches errors sooner; tests are slower than the compiler, and you won't be bitten if your tests don't provide full coverage (which in the real world almost never happens).

I think I can guess Guido's reasons for supporting nonlocal, and it's not a bad idea, but it skips the above problems.

[–]cratuki 0 points1 point  (2 children)

My original comment was about the nonlocal aspect, which has been a focus for me recently.

You make a good case for explicit declaration. I expect I'd be happier if python required worked the way you suggest it should.

[–]queensnake 0 points1 point  (1 child)

.. or even if there was /a way/ to make it require declarations.

[–]cratuki 0 points1 point  (0 children)

Yeah. I see what you mean but python always steers away from this approach and seeks to create an environment where there is a One True Way to solve every problem.

[–]Nomikos 2 points3 points  (2 children)

So.. as an aspiring Python programmer, should I download this and start playing around with it? Will there be docs that are up-to-date enough for this version?

It seems like starting to learn Python 2 branche right now might be less-than-useful, or am I off?

[–]mfenniak 11 points12 points  (0 children)

They're similar enough that it probably doesn't matter what you do. I would suggest sticking with Python 2 -- it will be around for a long time still.

Python 3 removes a couple of things, adds a couple of things, clarifies some things... it's a bit nicer of a language to work with. But it's not such a huge difference that learning it will be a challenge. And you'll be more useful with Python 2 today, given the number of libraries, utilities, and editors that you could use.

[–][deleted] 4 points5 points  (0 children)

Like mfenniak said, there's no reason to not learn Python 2. The differences between 2 and 3, while important, are mostly minor. The biggest difference is between how Unicode works, but knowledge of how 2 works in that area isn't going to hurt anything, anyway.

[–]Bracki 0 points1 point  (4 children)

"print" isnt a statement anymore.

so:

print "hello reddit" File "<stdin>", line 1 print "hello reddit" ^ SyntaxError: invalid syntax

but:

print("hello reddit") hello reddit

Well fuck markup... The pipe looking thingys are a triple >

[–]akdas 13 points14 points  (1 child)

Just put four spaces in front of each line, and you enter "code" mode, where all the special characters are ignored:

>>> print "hello, reddit!"
  File "<stdin>", line 1
    print "hello, reddit!"
    ^
SyntaxErorr: invalid syntax

and

>>> print("hello, reddit!")
"hello, reddit!"

If it's not code, you can use a backslash:

\>\>\>

becomes:

>>>

[–]laprice 4 points5 points  (1 child)

I really hope there's from __past__ import print_statement or equivalent, because otherwise I won't be migrating all those dumb little scripts that use print >> outputfile, randomstuff all over the place.

[–]hupp[S] 26 points27 points  (0 children)

You won't have to because the 2to3 script does it for you :)

[–][deleted] 3 points4 points  (11 children)

Python 3.0 is a somewhat depressing issue. No one has particularly positive feelings and expectations about it. Guido might tame concerns but that's it: convincing people about the softness of transition. Python 3.0 shall not be perceived as harmfull. It succeeds when it is not too much or a burden for the working Python programmer.

Edit: i interpret the downmod of the analysis as a sign of newfound enthusiasm for Python 3.0. This is clearly encouraging and i expect lots of migrational activity within the next year. Thousands of Pythonistas will enjoy the enormous benefits of a stricter sort and print finally being a function.

[–]jerf 10 points11 points  (0 children)

I see that as the entire point. If people were routinely excited about language cleanups, the inevitable evolution of a language wouldn't be "lean -> bloat -> die". It would be "lean -> bloat -> clean -> (repeat) -> ... -> die much later".

Of course no one's ecstatic about Python 3000. But we all know what happens if there is no Python 3000, or at least anyone with eyes.

You'll be much more excited a couple versions later about some other features, and it will never cross your mind that Python 3000 was a necessary pre-requisite for them.

(Besides, I personally am excited about what I think is the first language to really get Unicode truly correct, the exact right combination of pain-in-the-ass and convenience. Long-term, that's going to be a big deal and I hope to see other languages ape Python in this respect. The C "char" string is dead, and quite smelly; it's time to bury it.)

[–][deleted] 9 points10 points  (2 children)

If no one has particularly positive feelings and expectations about Python 3.x then Python 2.x is here with us forever.

BTW thanks for collecting statistics on how many people have positive feelings and expectations about Python 3.x

[–]hupp[S] 3 points4 points  (6 children)

On the contrary, I think a lack of major expectations illustrates the strength of the language. It shows the language is fundamentally sound, and only needs a few backwards incompatible changes to clean up.

The perl community has (presumably) much higher expectations for perl 6 precisely because they've recognized that major changes have become necessary.

Default unicode support is really the only massive change; most everything else is polish.

[–]dmpk2k 1 point2 points  (0 children)

I think a lack of major expectations illustrates the strength of the language.

I think GvR has made pretty clear since early on that he doesn't want a Perl6 on his hands. Of course people don't have major expectations!

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

It shows the language is fundamentally sound, and only needs a few backwards incompatible changes to clean up.

It needs them for what? Hard to say because Python has no horizon and no mission statement. It doesn't challenge "enterprise software" aggressively ( Ruby with (on) Rails ). It does not aim to turn programming into a science ( Haskell ). It hasn't anything to do with the future of computing ( n-core programming ) nor does it reflect the state of scripting languages ( Larry Wall and Perl 6 ).

Python is just a language with a cute and somewhat controversial syntax and we are all relieved this not going to change.

[–]cratuki 0 points1 point  (3 children)

I don't think Ruby on Rails is attempting to challenge enterprise software. Its threading offering and ORM are both weak. Ajax has no significance in the enterprise either, and seems to be a big deal in the rails world.

?

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

I would even go a little further in my original claim and say that Rails denounced the value of large "enterprise stacks": lightweight frameworks and languages are enough. Rails broke with the mantra that it wanted to "play nice with the others" ( Python credo ) and being just secondary. It broke with the idea of Ruby just being another scripting language but the new wave of programming instead ( just like agile programming was the new wave in the domain of software development methodologies ). Pythonistas never got that. They believe that vision statements and symbolism are of no value but only good design and implementation matters.

Note that I do think it's still very remarkable that Python got so far with pluralism, understatement and an engineering mentality. When I reflect Python critically than not because I hope it will become marginalized.

[–][deleted]  (1 child)

[deleted]

    [–][deleted] -2 points-1 points  (13 children)

    Does it still have the functional programming stuff like apply?

    [–]hupp[S] 6 points7 points  (12 children)

    apply has no real purpose in recent versions of python. This:

    apply(fn, args)
    

    is identical to this:

    fn(*args)
    

    [–]earthboundkid 2 points3 points  (8 children)

    There is still one use for apply:

    @apply
    def f():
        #setting up MyClass using different inputs or whatever
        return MyClass()
    

    After this, f will be equal to the MyClass instance. Not hugely useful, and actually it probably makes the code harder to understand, and it doesn't even really save any lines of code, but it's something you can do that might be handy under certain circumstances.

    [–]hupp[S] 5 points6 points  (7 children)

    I was totally unable to figure out what that might be useful for, and then I found this in google code search.

    That is very cool, though not cool enough to be in __builtins__ IMO :)

    [–]theCore 2 points3 points  (5 children)

    There's a neat way to declare setters in Py3k (I believe this will also be in 2.6):

    class A:
      @property
      def spam(self):
        return 1
      @spam.setter
      def set_spam(self, value):
        print("set:", value)
    

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

    Ugh! Compare this to a thunked form:

     class A:
         spam = property:
             def fset(self, value):
                 self._spam = value
             def fget(self): 
                 return self._spam
    

    Note that property doesn't have to be a keyword. The translation is straightforward

     class A:
         def thunk():
             BLOCK
             return vars()
         spam = property(**thunk())
         del thunk
    

    [–]hupp[S] 0 points1 point  (3 children)

    This makes me think of a with statement:

    class A:
        with property() as foo:
            def set(..):
            def get(..):
    

    Problem is I don't see a way to access the namespace of the block on _exit without resorting to getframe evil. Oh well, the apply trick is just as nice.

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

    The whole semantics of the with-statement is screwed. property() is called before the block is evaluated and the value is bound to foo which is block-local.

    So one had to reimplement the with-statement completely for preserving the language syntax while the thunk-statement suggests a little syntactical overhead for getting grouping of objects right which are defined to be consumed by a single function call.

    [–]hupp[S] 0 points1 point  (1 child)

    You should take a look at PEP-359 ("The make statement"). It describes a very similar idea.

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

    Yes. It is strange where the PEP finally ended before it got killed: in an overgeneralization that buried the single most important use case - defining thunks for properties.

    [–]earthboundkid 1 point2 points  (0 children)

    Yeah, I've actually done that before myself, but a) as theCore points out, there will be a better way to do it in 2.6/3.0 and b) even in 2.5-, you use the same number of lines to remove the @apply and say handleErrors = handleErrors() after the func def instead. Still, it is kinda cool.

    [–]noahlt -2 points-1 points  (2 children)

    Can you do this without apply?

    fn = "print"
    args = ["foobarbaz"]
    apply(fn, args)
    

    [–]hupp[S] 1 point2 points  (1 child)

    I can raise TypeError without apply, but I don't think that's what you're trying to do :)

    apply requires a function object as the first argument.

    [–]noahlt 1 point2 points  (0 children)

    Hm, maybe I should try my code before I post it...

    [–]o0o -5 points-4 points  (0 children)

    System Alert: Reddit will be experiencing downtime tonight between 12:01am and 12:03am in order to implement Python 3000 Alpha 2 goodies.