class inheritance python2.7 vs python3.3

2014-01-06 Thread jwe . van . dijk
I have problems with these two classes:

class LPU1():
def __init__(self, formula):

formula is a string that is parsed into a SymPy function
and several derived functions

self.formula = formula
... ...

class LPU3(LPU1):
def __new__(self):

the same functions as LPU1 but some added functions
and some functions redefined

... ...

if __name__ == '__main__:
y = y = 'x_0 * x_1 + x_2'
stats1 = LPU1(y)
stats3 = LPU3(y)

Worked perfectly on Python 2.7.5+ but on Python 3.3.2+ I get on 
instantiatiating stat3:
TypeError: __new__() takes 1 positional argument but 2 were given

What am I doing wrong?
I must confess I am a bit out of my depth here so any explanation will be a 
learning experience.

Many thanks, Janwillem
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: class inheritance python2.7 vs python3.3

2014-01-06 Thread Chris Angelico
On Tue, Jan 7, 2014 at 4:14 AM,  jwe.van.d...@gmail.com wrote:
 class LPU3(LPU1):
 def __new__(self):
 
 the same functions as LPU1 but some added functions
 and some functions redefined
 

You probably don't want to be using __new__ here. Try using __init__
instead, or simply not defining __new__ at all.

I suspect that the reason that appears to work under Py2 is that
you're using an old-style class, there. That means it'll be subtly
different on the two versions. To make them do the same thing,
explicitly subclass object:

class LPU1(object):

In Python 3, that's redundant - subclassing object is the default. In
Python 2, though, it's important.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: class inheritance python2.7 vs python3.3

2014-01-06 Thread Dave Angel

On Mon, 6 Jan 2014 09:14:08 -0800 (PST), jwe.van.d...@gmail.com wrote:

I have problems with these two classes:




class LPU1() :


You forgot to derive from object. That's implied on 3.x, but you say 
you're also running on 2.7  Without naming your base class you're 
asking for an old style class which has been obsolete maybe 10 years. 
I sure don't recall how it differs.



def __init__(self, formula):

formula is a string that is parsed into a SymPy function
and several derived functions

self.formula = formula
... ...




class LPU3(LPU1):
def __new__(self):

the same functions as LPU1 but some added functions
and some functions redefined


You don't show where you call super, so we can't tell what you had in 
mind. And did you actually mean __new__ here or should you have 
defined __init__ as you did in the base class?



if __name__ == '__main__:
y = y = 'x_0 * x_1 + x_2'
stats1 = LPU1(y)
stats3 = LPU3(y)


And where did you expect that y to go?


Worked perfectly on Python 2.7.5+ but on Python 3.3.2+ I get on 

instantiatiating stat3:

I don't see anything called stat3. Presumably you mean stats3, but 
you're not instantiating it you're instantiating LPU3.



TypeError: __new__() takes 1 positional argument but 2 were given


You forgot to include the rest of the stack trace.


I think the real problem is you forgot to include the second 
parameter on the misnamed __init__ method. It should have parameters 
self and arg, and pass arg up through super.


--
DaveA

--
https://mail.python.org/mailman/listinfo/python-list


Re: class inheritance python2.7 vs python3.3

2014-01-06 Thread Steven D'Aprano
jwe.van.d...@gmail.com wrote:

 I have problems with these two classes:
 
 class LPU1():
 def __init__(self, formula):
 
 formula is a string that is parsed into a SymPy function
 and several derived functions
 
 self.formula = formula
 ... ...
 
 class LPU3(LPU1):
 def __new__(self):
 
 the same functions as LPU1 but some added functions
 and some functions redefined
 
 ... ...

If this actually is your class, then in Python 2.7 the __new__ method will
do nothing at all.

However, if you actually inherited from object in LPU1, then it (might) work
in Python 2.7. In Python 3.3, it will work regardless. Perhaps you have a
bug in the __new__ method? In Python 2.7, it is never called, and so the
bug never occurs. In Python 3.3, it is called, and the bug occurs.


 Worked perfectly on Python 2.7.5+ but on Python 3.3.2+ I get on
 instantiatiating stat3: TypeError: __new__() takes 1 positional argument
 but 2 were given

And sure enough, that's exactly it.



 What am I doing wrong?
 I must confess I am a bit out of my depth here so any explanation will be
 a learning experience.

Back in the Dark Ages of Python 1.x, built-in types like int, str, list and
so forth were completely independent of classes created with the class
statement. So you couldn't subclass them.

In Python 2.2, Python underwent what was called class/type unification,
which added a new mechanism to allow built-in types to be subclassed. For
reasons of backward compatibility, the existing classes were left alone,
and were called old style or classic classes. But a new built-in,
called object, was created. All the other built-in types (str, list, int,
etc.) inherit from object. These became known as new style classes.

New style classes had extra features that classic classes don't have,
including the __new__ constructor method. (Classic classes don't let you
override the constructor, only the initializer, __init__. New-style classes
let you override both.)

So Python 2.2 and beyond has two distinct models for classes, which *mostly*
work the same but have a few differences -- those that inherit from object
or some other built-in type, and those that don't.

# Python 2 classic class:
class LPU1():
 def __new__(cls): ...

__new__ is dead code here, and won't be called.

# Python 2 new-style class:
class LPU1(object):
 def __new__(cls): ...

__new__ is called.

So when you inherit from LPU1, your LPU3 class gets the same old
versus new behaviour, and __new__ is either dead code or not.

Now fast forward to Python 3. In Python 3, having two types of classes was
considered one too many. The old-style classes were dropped. Inheriting
from object became optional. Either way, you would get the same behaviour,
and __new__ is always used. So if you have a buggy __new__ method, it could
be ignored in Python 2 and suddenly run in Python 3, giving you an error.



-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: class inheritance python2.7 vs python3.3

2014-01-06 Thread jwe . van . dijk
On Monday, 6 January 2014 18:14:08 UTC+1, jwe.va...@gmail.com  wrote:
 I have problems with these two classes:
 
 
 
 class LPU1():
 
 def __init__(self, formula):
 
 
 
 formula is a string that is parsed into a SymPy function
 
 and several derived functions
 
 
 
 self.formula = formula
 
 ... ...
 
 
 
 class LPU3(LPU1):
 
 def __new__(self):
 
 
 
 the same functions as LPU1 but some added functions
 
 and some functions redefined
 
 
 
 ... ...
 
 
 
 if __name__ == '__main__:
 
 y = y = 'x_0 * x_1 + x_2'
 
 stats1 = LPU1(y)
 
 stats3 = LPU3(y)
 
 
 
 Worked perfectly on Python 2.7.5+ but on Python 3.3.2+ I get on 
 instantiatiating stat3:
 
 TypeError: __new__() takes 1 positional argument but 2 were given
 
 
 
 What am I doing wrong?
 
 I must confess I am a bit out of my depth here so any explanation will be a 
 learning experience.
 
 
 
 Many thanks, Janwillem

Thanks for all the contributions. I now have:
class LPU1(object):
def __init__(self, formula):
... ...
and
class LPU3(LPU1):
def __init__(self, y):
LPU1.__init__(self, y)
   ... ...

which gives the correct results both on 2.7 and 3.3.
Is that more or less good practice?
Now I stumble on a SymPy problem under 3.3 but that obviously is an other topic
Cheers, janwillem
-- 
https://mail.python.org/mailman/listinfo/python-list