473,378 Members | 1,510 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

lazy arithmetic


# This is what I have in mind:

class Item(object):
def __add__(self, other):
return Add(self, other)

class Add(Item):
def __init__(self, a, b):
self.a = a
self.b = b

a = Item()
b = Item()

c = a+b

# Now, I am going absolutely crazy with this idea
# and using it in a big way. So I'm looking at
# automating the process. As a first step,
# I thought maybe this would work:

class Item(object):
pass

class Add(Item):
def __init__(self, a, b=None):
print self, a, b
self.a = a
self.b = b

Item.__add__ = Add

x = Item()
y = Item()

print x, y

c = x+y

# This time, the Add constructor gets only the first two arguments:
"self" and "y".
# So, what happened to "x" ? Is this some kind of property voodoo going
on ?

# Simon.

Aug 25 '06 #1
10 1389
At Friday 25/8/2006 00:36, pi**********@gmail.com wrote:
># This is what I have in mind:

class Item(object):
def __add__(self, other):
return Add(self, other)
And this works fine... why make thinks complicated?
># Now, I am going absolutely crazy with this idea
# and using it in a big way. So I'm looking at
# automating the process. As a first step,
# I thought maybe this would work:

class Item(object):
pass

class Add(Item):
def __init__(self, a, b=None):
print self, a, b
self.a = a
self.b = b

Item.__add__ = Add
This doesn't make sense... __add__ should be a method, not a class...

>x = Item()
y = Item()

print x, y

c = x+y

# This time, the Add constructor gets only the first two arguments:
"self" and "y".
# So, what happened to "x" ? Is this some kind of property voodoo going
on ?
x+y get translated to x.__add__(y)
x.__add__ is Add (the class), so Python calls Add, which means using
it as a constructor with y as the (only) argument.
So you see in the __init__ method: self=a new instance of Add, a=y,
b=None (default, as only one argument was provided).

If you really want to "inject" __add__ into the Item class, you could
use a factory:

def AddFactory(a,b):
return Add(a,b)
Item.__add__ = AddFactory

(but as you've said yourself, that's a bit crazy...)
Gabriel Genellina
Softlab SRL

__________________________________________________
Preguntá. Respondé. Descubrí.
Todo lo que querías saber, y lo que ni imaginabas,
está en Yahoo! Respuestas (Beta).
¡Probalo ya!
http://www.yahoo.com.ar/respuestas

Aug 25 '06 #2
pi**********@gmail.com wrote:
# This is what I have in mind:

class Item(object):
def __add__(self, other):
return Add(self, other)

class Add(Item):
def __init__(self, a, b):
self.a = a
self.b = b

a = Item()
b = Item()

c = a+b

# Now, I am going absolutely crazy with this idea
# and using it in a big way. So I'm looking at
# automating the process. As a first step,
# I thought maybe this would work:

class Item(object):
pass

class Add(Item):
def __init__(self, a, b=None):
print self, a, b
self.a = a
self.b = b

Item.__add__ = Add

x = Item()
y = Item()

print x, y

c = x+y

# This time, the Add constructor gets only the first two arguments:
"self" and "y".
# So, what happened to "x" ? Is this some kind of property voodoo going
on ?

# Simon.
Look at the signature for __add__:

__add__(self, other)

Now look at the signature for __init__:

__init__(self, a, b=None)

Now look at the output of your script:

|>>
<__main__.Item object at 0xb6faa4ac<__main__.Item object at
0xb6faa3ec>
<__main__.Add object at 0xb6faa5ec<__main__.Item object at
0xb6faa3ecNone
When python calls x.__add__ as a result of "x+y" it only passes it y as
'other', or, in this case, as 'a'. The 'self' arg gets filled in with
a brand new Add instance, because __add__ (rather than being a method
of Item) is really the class Add. (b will never be filled in using the
Add.__init__ method this way.)

Consider:

|>x
<__main__.Item object at 0xb6f10f0c>
|>x.__add__
<class '__main__.Add'>
|>Badd = x.__add__
|>Badd
<class '__main__.Add'>
|>b = Badd(23, 18)
<__main__.Add object at 0xb6f10e8c23 18
|>b
<__main__.Add object at 0xb6f10e8c>

Make more sense? :-)

"Item.__add__ = Add" is a very strange thing to do, I'm not surprised
it didn't work.

HTH,
~Simon

Aug 25 '06 #3

Gabriel Genellina wrote:
At Friday 25/8/2006 00:36, pi**********@gmail.com wrote:
# This is what I have in mind:

class Item(object):
def __add__(self, other):
return Add(self, other)

And this works fine... why make thinks complicated?
Yes, I agree it's simpler, and up until now that's the way
I always did it. Many Many times.
Now I am looking for a way to build ensembles of these lazy classes at
the meta-level.
(think abstract algebra).
Item.__add__ = Add

This doesn't make sense... __add__ should be a method, not a class...
No, that's not true. It can be this callable:

def add(a, b):
return Add(a,b)
Item.__add__ = add

So my thinking was this: why can't I use a callable class ?
x+y get translated to x.__add__(y)
No that's not true at all. The self argument to __add__ ends
up being the Add instance, not the Item instance:

z=x+y is translated to z.__add__(y)

Simon.

Aug 25 '06 #4

Simon Forman wrote:
>
"Item.__add__ = Add" is a very strange thing to do, I'm not surprised
it didn't work.
Yes it is strange.
I also tried this even stranger thing:

class Item(object):
class __add__(object):
def __init__(self, a, b=None):
print self, a, b
self.a = a
self.b = b

:)

Simon.
>
HTH,
~Simon
Aug 25 '06 #5
pi**********@gmail.com wrote:
Gabriel Genellina wrote:
At Friday 25/8/2006 00:36, pi**********@gmail.com wrote:
># This is what I have in mind:
>
>class Item(object):
def __add__(self, other):
return Add(self, other)
And this works fine... why make thinks complicated?

Yes, I agree it's simpler, and up until now that's the way
I always did it. Many Many times.
Now I am looking for a way to build ensembles of these lazy classes at
the meta-level.
(think abstract algebra).
>Item.__add__ = Add
This doesn't make sense... __add__ should be a method, not a class...

No, that's not true. It can be this callable:

def add(a, b):
return Add(a,b)
Item.__add__ = add
But that's a function, not a class. When you assign add to an
attribute of Item it "magically" becomes a method of Item:

|>add
<function add at 0xb6f3b95c>
|>Item.__add__
<unbound method Item.add>
|>x.__add__
<bound method Item.add of <__main__.Item object at 0xb6f3af2c>>

So it works fine.

>
So my thinking was this: why can't I use a callable class ?
When you assign a class to an attibute (be it __add__ or __banana__ or
anything else) the "magic" doesn't take place:

|>Add
<class '__main__.Add'>
|>Item.__banana__ = Add
|>Item.__banana__
<class '__main__.Add'>
x+y get translated to x.__add__(y)

No that's not true at all. The self argument to __add__ ends
up being the Add instance, not the Item instance:
No, that's *exactly* true. "x+y" does mean "x.__add__(y)" and
"x.__add__" *is* the class Add, so you're really calling "Add(y)",
nothing more nor less.

x+y =>
x.__add__(y) =>
(x.__add__)(y) =>
Add(Y) =>
Hello new Add instance, here's a y for you... :-)
>
z=x+y is translated to z.__add__(y)
Nope. Just plain wrong. Not sure why you'd think that.
(No offense intended.)

Peace,
~Simon F.
>
Simon.
Aug 25 '06 #6

pi**********@gmail.com wrote:
Simon Forman wrote:

"Item.__add__ = Add" is a very strange thing to do, I'm not surprised
it didn't work.

Yes it is strange.
I also tried this even stranger thing:

class Item(object):
class __add__(object):
def __init__(self, a, b=None):
print self, a, b
self.a = a
self.b = b

:)

Simon.
That didn't work either did it? :-)

~Simon F.

Aug 25 '06 #7
At Friday 25/8/2006 02:18, pi**********@gmail.com wrote:
x+y get translated to x.__add__(y)

No that's not true at all. The self argument to __add__ ends
up being the Add instance, not the Item instance:

z=x+y is translated to z.__add__(y)
Well, I deleted my response after I noticed that Simon Forman has
done it very well.
Just a note: print z after this line and compare with self inside
__init__ if you're still not convinced.

Gabriel Genellina
Softlab SRL

__________________________________________________
Preguntá. Respondé. Descubrí.
Todo lo que querías saber, y lo que ni imaginabas,
está en Yahoo! Respuestas (Beta).
¡Probalo ya!
http://www.yahoo.com.ar/respuestas

Aug 25 '06 #8
pi**********@gmail.com wrote:
# This is what I have in mind:

class Item(object):
def __add__(self, other):
return Add(self, other)

class Add(Item):
def __init__(self, a, b):
self.a = a
self.b = b

a = Item()
b = Item()

c = a+b

# Now, I am going absolutely crazy with this idea
# and using it in a big way. So I'm looking at
# automating the process. As a first step,
# I thought maybe this would work:

class Item(object):
pass

class Add(Item):
def __init__(self, a, b=None):
print self, a, b
self.a = a
self.b = b

Item.__add__ = Add

x = Item()
y = Item()

print x, y

c = x+y

# This time, the Add constructor gets only the first two arguments:
"self" and "y".
# So, what happened to "x" ? Is this some kind of property voodoo going
on ?
Indeed. Read up on descriptors:

http://users.rcn.com/python/download/Descriptor.htm

The following seems to work:

from new import instancemethod

class Add:
class __metaclass__(type):
def __get__(self, inst, cls):
if inst is None:
return cls
return instancemethod(cls, inst, cls)
def __init__(self, a, b=None):
self.a = a
self.b = b
def __str__(self):
return "%s(%s, %s)" % (self.__class__.__name__, self.a, self.b)

Add.__add__ = Add
print Add(1, 2) + 42

but makes the simple

def __add__(self, other):
return Add(self, other)

all the more attractive.

Peter
Aug 25 '06 #9

Simon Forman wrote:
But that's a function, not a class. When you assign add to an
attribute of Item it "magically" becomes a method of Item:
Yes, I am looking to understand this magic.
Sounds like I need to dig into these descriptor thingies (again).

(sound of brain exploding)..

Simon.

Aug 25 '06 #10
<pi**********@gmail.comwrote:
Simon Forman wrote:
But that's a function, not a class. When you assign add to an
attribute of Item it "magically" becomes a method of Item:

Yes, I am looking to understand this magic.
Sounds like I need to dig into these descriptor thingies (again).

(sound of brain exploding)..
It's really very simple: Python-coded functions (whether their def is in
a classbody or not) are descriptors (objects with a method named __get__
which binds the first argument); classes (and C-coded functions, etc)
are not descriptors (they have no method named __get__ etc etc). If you
insist, you can write a custom metaclass with a __get__ so that classes
instantiating it ARE descriptors, for example.
Alex
Aug 25 '06 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

25
by: Steven Bethard | last post by:
So I end up writing code like this a fair bit: map = {} for key, value in sequence: map.setdefault(key, ).append(value) This code basically constructs a one-to-many mapping -- each value that...
3
by: Jeff Johnson [MVP: VB] | last post by:
What is the point of lazy * and lazy ? ? "Nothing" will always succeed first, right? If not, can someone give me an example of when either of these might be used?
4
by: Siemel Naran | last post by:
What is a good idiom for handling a lazy object? I see 2 good possibilities. Any more, any comments? Which way do people here use? (1) class Thing { public: Thing(double x, double y) :...
16
by: TTroy | last post by:
Hello, I'm relatively new to C and have gone through more than 4 books on it. None mentioned anything about integral promotion, arithmetic conversion, value preserving and unsigned preserving. ...
4
by: PDHB | last post by:
I'm sorry, but this is just the height of stupidity. I love the dot net framework. It has actually been sufficient to convert an anti-microsoft extremist (myself) to the windows camp. But not...
7
by: barikat | last post by:
int a; int *Ptr1, *Ptr2; Ptr1 = a; Ptr1++; Ptr2 = a; printf("Ptr1 : %p\n", Ptr1); printf("Ptr2 : %p\n\n", Ptr2);
26
by: Bill Reid | last post by:
Bear with me, as I am not a "professional" programmer, but I was working on part of program that reads parts of four text files into a buffer which I re-allocate the size as I read each file. I...
39
by: Boltar | last post by:
Why does C do lazy evaluation for logical boolean operations but not bitwise ones? Ie: the following program prints "1 2" , not "1 1" under gcc main() { int a = 1; int b = 1; 0 && ++a;
6
by: Peng Yu | last post by:
Hi, I'm wondering if the following assignment is lazy copy or not? Thanks, Peng std::vector<intv. v.push_back(1); v.push_back(2);
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.