[Edu-sig] What edu-sig page advice to give re 3.x vs 2.x in 2014?

Kirby Urner kurner at oreillyschool.com
Thu May 29 21:57:17 CEST 2014


I wonder what other edu-siggers think about our advice on the edu-sig page
regarding 2.x versus 3.x Python, i.e. which to learn and invest in more.

Obviously there's no one size fits all, but with the passage of time we may
want to revise our advice-giving.

Per the example email below, me responding to a student, in 2.x if you
didn't subclass object explicitly, then your @property attributes would not
be inherited, as demonstrated by the example code below.

Such discrepancies can lead to frustration especially if following
tutorials or documentation and thinking version might not matter that
much.

Newcomers do not spontaneously assume or intuitively know that 3.x is
backward incompatible with 2.x, as if the number change actually conveys
that message; it doesn't, we have to let them know, give a heads up.

I'm personally quite happy with 3.x and find it a great improvement over
2.x and my bias would be to encourage learning 3.x first and any 2.x
version as a dialect later.

Enough 3rd party products have made the transition to where I don't think
we need to circle 2.x as much in our advice-giving (whereas when this
advice was first given, 3.x was still quite new).

Kirby Urner
O'Reilly School of Technology


Email reply to student:
=====================

Yes, behavior appears to have changed.

If you have the time, I think a worthy exercise, try your 2.7
code but with your class Parent subclassing from (object).

Wait, I have a 2.7 interpreter, lets see what I get:

Python 2.7.3 (v2.7.3:70274d53c1dd, Apr  9 2012, 20:32:06)
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "copyright", "credits" or "license()" for more information.
>>> from inheritance_test import Parent, Child
>>> obj = Child()
>>> obj.name = "Kirby"
>>> obj.name
'Kirby'
>>> obj.name = "Johnathan"
>>> obj.name
'Johnathan'

This is where I force a recompile of the module, after I make
Parent a subclass of object explicitly, object being the "new
style class" 2.7 was phasing in, with 3.x using new style classes
exclusively.

>>> import imp
>>> import inheritance_test
>>> imp.reload(inheritance_test)
<module 'inheritance_test' from 'inheritance_test.py'>
>>> from inheritance_test import Parent, Child
>>> obj = Child()
>>> obj.name = "Johnathan"

Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    obj.name = "Johnathan"
  File "inheritance_test.py", line 9, in name
    raise AttributeError
AttributeError

I'm glad you raised this issue.  Guido van Rossum took a risk in
announcing his "PY2K" apocalypse around 2000:  a backward incompatible
leap that would fix some fundamental errors he felt he'd made with
the 2.0 edition.  Perl tried to make the leap from 5 to 6 and is
still trying.  On the other hand, Python 3.x has some pleasing
and consistent features that argue well for Guido's risk taking.

Kirby


------------------------------------------------------------------
Please keep this line in the subject of all messages in this case:
        [CASE-9761146]
------------------------------------------------------------------

On Thu, 29 May 2014 at 11:42 AM, Rafael Chavez wrote:

 > So, I got your response.  I tried your example in Python 2.7 and in the
 > console in Eclipse in Python 3.  I get 2 different Results.  Has this
 > behavior change from 2.7 to 3 or am I doing something wrong?
 >
 > In Python 2.7:
 > >>> class Parent:
 >     @property
 >     def name(self):
 >         return self._name
 >
 >     @name.setter
 >     def name(self, n):
 >         if n != "Kirby":
 >             raise AttributeError
 >         self._name = n
 >
 >
 > >>> class Child(Parent):
 >     pass
 >
 > >>> obj = Child()
 > >>> obj.name = "Kirby"
 > >>> obj.name
 > 'Kirby'
 > >>> obj.name = "Joe"
 > >>> obj.name
 > 'Joe'
 > >>> dir(obj)
 > ['__doc__', '__module__', 'name']
 > >>> obj1 = Child()
 > >>> obj1
 > <__main__.Child instance at 0x02B92F58>
 > >>> dir(obj1)
 > ['__doc__', '__module__', 'name']
 > >>> obj.name
 > 'Joe'
 > >>> obj1.name = "Joe"
 > >>> obj1.name
 > 'Joe'
 > >>> try:
 >     obj.name = "Jonathan"
 > except:
 >     print("NOT KIRBY")
 > >>>
 > >>> obj.name
 > 'Jonathan'
 > >>>
 >
 >
 > In Python 3:  -- As expected:
 > class Parent:
 >     @property
 >     def name(self):
 >         return self._name
 >
 >     @name.setter
 >     def name(self, n):
 >         if n != "Kirby":
 >             raise AttributeError
 >         self._name = n
 >
 > class Child(Parent):
 >     pass
 >
 >
 > obj = Child()
 > obj.name = "Kirby"
 > obj.name
 > 'Kirby'
 > print(obj.name)
 > Kirby
 >
 > try:
 >     obj.name = "Joe"
 > except:
 >     print("It did not work")
 >
 > It did not work
 >
 >
 > Thanks,
 >
 > XXX  [ student name redacted ]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/edu-sig/attachments/20140529/0f3ae19c/attachment-0001.html>


More information about the Edu-sig mailing list