Python 3000

Embed Size (px)

Citation preview

Python 3.0 (Py3K) Introduction

Authors:timchen119.nospam.at.gmail.com ()

Location: Taiwan COSCUP 2008

Date: 2008/08/24

Blog: http://timchen119.blogspot.com

This document has licensed as CC-SA 2.0

Topic

Introduction

New syntax

New Feature

Migratation

Introduction

Python is a dynamic object-oriented programming language that can be used for many kinds of software development.

Last Stable Release: Python 2.5.2 (February 22, 2008)

Last Beta Release: Python 2.6beta2 and 3.0beta2 (July 17, 2008)

Python 3000, Python 3.0 and Py3K are all names for the same thing.

Introduction (cont.)

The actual Python release will be referred as Python 3.0.

Sep 03 2008: Python 2.6 and 3.0 final released. (planned)

Python 2.6: a transitional release to help prepare code for Python 3.0.

Python 3.0 IS...

backwards-incompatible.

remove some previous design mistakes.

reviewing and improving standard library modules.

django and some python modules may have tools to generate python 2.x/3.0 code from single code base.

What is NOT changed

Guido said in PEP 3099. (PEP: Python Enhancement Proposals)

Python 3000 will NOT be a rewrite from scratch.

Python 3000 will NOT be case-insensitive.

self will NOT become implicit.

What is NOT changed (cont.)

lambda will NOT be renamed.

NO braces. (from __future__ import braces)

The global statement WILL stay.

print()

from statement to function

2.x you can: print("Hello") or print "Hello"

3.0 you have to add ()

raw_input(now input) was a function

print >> open("test.txt","w"), "1","2","3" (X)

print("1", "2", "3", file=open("test.txt","w")) (O)

format()

in python 2.x::

t=[1,2,3];"abc%s" % t -> 'abc[1, 2, 3]'

t=(1,2,3);"abc%s" % t -> TypeError

format() #PEP 3101

can define __format__() special method

"%14.12s" % "hello world! hello!"

==>

format("Hello world! Hello World!",">14.12")

Python 3.0 Hello World 101

print("hello world!")

(lambda:print("hello world!"))()

print("hello {what}".format(what='world!'))

print("{0} {1}".format('hello','world!'))

print("hello {0.name}".format(open('world!', 'w')))

print("hello {0[what]}".format(dict(what='world!')))

print("hello {0[what]}".format({'what':'world!'}))

unicode

unicode(charset) is not utf-8 (bytestring).

unicode == str now. (no unicode type in 3.0)

add a bytes type, bytes('test','utf-8')

''.encode('utf-8')==> b'\xe9\x96\x8b\xe6\xba\x90'

''.encode('cp950')==> b'\xb6}\xb7\xbd'

Unicode(2.x) -> str(3.x)

str(2.x) -> bytes(3.x)

abc,collections

PEP 3119

Abstract Base Class

module collections

OOP term 'Invocation' : object.method() ==> implies polymorphis

polymorphism: 'type-of object'.method() : may run different code when types different.

duck typing polymorphism: assume object is a duck if it can quacks. -- inspection style, check from external. (did not use object's method to check)

a situation without using abc

Situation: you want to accept iterables from one of following datatypes: dict or tuples.

you use hasattr(my_iterables,'items')

may lead to unexpected behavior.

does it support dict-like objects? isn't that main advantages to use duck-typing ?

what is a dict?

abc,collections (cont.)

there maybe a dict without __contains__ and have has_key() function.

here comes abc ==> Abstract base classes

what to inspect? there are too many stuffs in a python object to check.

abc and collection modules intends to answer these questions:

what is a 'MutableMapping' ?

what is a 'Iterable' ?

and what is a 'MyAbstractType' ?

abc,collections (cont.)

isinstance([], collections.MutableSequence)

@abstractmethod, @abstractproperty

abc example

http://lucumr.pocoo.org/cogitations/tag/py3k/

Python2

try:

iter(obj)

except TypeError:

do_something_with_not_iterable_object(obj)

else:

do_something_with_iterable_object(obj)

abc example (cont.)

Python3

from collections import Iterable

if isinstance(obj, Iterable):

the_object_is_iterable()

else:

the_object_is_not_iterable()

abc (cont.)

your custom class doesn't need to inherit from the base class.

how to do it?

collections.Iterable.register(myclass)

how to register your module to abc:

from _yourlinkedlist import YourLinkedList

from collections import Sequence

Sequence.register(YourLinkedList)

abc (cont.)

your C extension module works great.

io.IOBase, io.BufferedIOBase

StringIO,cStringIO --> io

abc --> the pythonic way to do both traditional OOP and duck-typing polymorph in the same time.

"There should be one and preferably only one obvious way to do it".

nonlocal

PEP 3104

python 2.1+ name resolution: LEGB (local => enclosed => global => builtins)

nested scoping was added when python 2.1 introduced.

local was always first checked, so if you assigned a local varible in a scope it assume that 'name' is a local, it's too bad for a closure.

there was some working arounds, however python 3.0 add a keyword: nonlocal.

closure (it's read-only)

python 2.x

def get_counter_py2():

x = 0

def f():

x += 1

return x

return f

add1 = get_counter_py2()

print add1();print add1();print add1()

closure (it's read-only)

python 2.x error::

Traceback (most recent call last):

File "counter.py", line 10, in

print next()

File "counter.py", line 4, in f

x += 1

UnboundLocalError:

local variable 'x' referenced before assignment

closure(cont.)

closure working around in 2.x (1):: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/474122

def get_counter_traditional():

x = [0]

def f():

x[0] += 1

return x[0]

return f

closure(cont.)

closure working around in 2.x (2)::

def get_counter_neat():

def f():

f.x += 1

return f.x

f.x = 0

return f

"To describe something as clever is NOT considered a compliment in the

Python culture." -- Alex Martelli (Python Cookbook 2nd.)

closure with nonlocal(cont.)

py3k used nonlocal::

def get_counter_py3k():

x=0

def f():

nonlocal x

x += 1

return x

return f

add1 = get_counter_py3k()

print(add1());print(add1());print(add1())

closure with nonlocal(cont.)

py3k used nonlocal::

def get_counter_py3k(x):

def f():

nonlocal x

x += 1

return x

return f

next = get_counter_py3k(1) print(add1());print(add1());print(add1())

* "There should be one and preferably only one obvious way to do it".

function annotations

PEP 3107 -- completely optional.

def foo(a: 'x' , b: 5 + 6 , c: list = [5,2,3]) -> max(2, 9): pass

foo.__annotations__ -> {'a': 'x', 'c': , 'b': 11, 'return': 9}

you could think as a compile time comment for function.

intend to used by third-party libraries. ie: typecheck

"There should be one and preferably only one obvious way to do it".

Misc.

__package__::

PEP 366 -- Main module explicit relative imports

Extended unpacking::

x,*y = range(6)

a,b,*c = {1:2,3:4,5:6}

Misc. (cont.)

map() filter() reduce() and list compresion::

map() and filter() becomes iterator and still in builtins

reduce() placed in functools module

range()::

next(range(10)) : TypeError: range object is not an iterator

migrate py3k use 2to3

* /usr/bin/2to3 (/usr/local/bin/2to3)

2to3 -w 2.py::

--- 2.py (original)

+++ 2.py (refactored)

@@ -1,1 +1,1 @@

-print 'hi'

+print('hi')

RefactoringTool: Files that were modified:

RefactoringTool: 2.py

Conclude

a lot of stuff changed. (there're still lots of stuff we don't mention changed!)

you could still use python 2.x and wait python 3.x matures.

2.6+ will recieve backports from python 3.0

from __future__ import py3k

Klicken Sie, um das Format der Notizen zu bearbeiten