What edu-sig page advice to give re 3.x vs 2.x in 2014?
![](https://secure.gravatar.com/avatar/7463903184144f767c080f0f6d2cb5c4.jpg?s=120&d=mm&r=g)
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 ]
participants (1)
-
Kirby Urner