Operator overloading and __getattr__

S

Samuel Kleiner

I'm trying to create methods on method access- but __getattr__ fails
with operator overloading(below) Any suggestions? EG:

class NewM(dict):
def __getattr__(self,name):
def fi(m):
if type(name) in self:
self[type(name)]=self[type(name)].__dict__[name](m)
else:
self[type(name)]=m
return fi

p=int(2)
s=NewM()
print p.__add__(2)
print s.__add__(2)
print p+2
print s+2

Causes TypeError on the last line
 
B

Bengt Richter

I'm trying to create methods on method access- but __getattr__ fails
with operator overloading(below) Any suggestions? EG:
First please explain why you are trying to do whatever it is you're trying to do ;-)
What do you mean "create methods"? A method like __add__ is returned by
the attribute mechanism as a bound method, with self bound to something, and
other being bound during the call of the method to the other operand. You
are apparently trying to intercept this for _instance_ attribute access, when
there exists no same_named method in class NewM or dict (since lookup of methods
will bypass __getattr__ for new style classes). (Maybe you want to override __getattribute__,
which is trickier, but I still don't know how you are going to supply a compatible pair
of operands for __add__ unless you hope to do something useful by ignoring self. But
a method grabbed from some random operand is not going to do that, in general). So what
are you trying to do? I seem to be missing it.

What do you expect to be self and other in this scenario?
BTW, IWT type(name) would be str all the time, so I don't know what the code
is doing, or even trying to do ;-/
class NewM(dict):
def __getattr__(self,name):
def fi(m):
if type(name) in self:
self[type(name)]=self[type(name)].__dict__[name](m)
else:
self[type(name)]=m
return fi

p=int(2)
s=NewM()
print p.__add__(2)
print s.__add__(2)
print p+2
print s+2

Causes TypeError on the last line
I doubt if that's the first problem ;-)

Regards,
Bengt Richter
 
J

John Roth

Samuel Kleiner said:
I'm trying to create methods on method access- but __getattr__ fails
with operator overloading(below) Any suggestions? EG:

I haven't a clue what you're trying to do, but
I believe it's not possible to install "magic methods"
after the class is defined. Nor can you install
them in the instance. They'll look like they've
been installed, but the interpreter will never
execute them because it does not look there
for them. It looks in special places in the C
language structure for the class definition.

John Roth
class NewM(dict):
def __getattr__(self,name):
def fi(m):
if type(name) in self:
self[type(name)]=self[type(name)].__dict__[name](m)
else:
self[type(name)]=m
return fi

p=int(2)
s=NewM()
print p.__add__(2)
print s.__add__(2)
print p+2
print s+2

Causes TypeError on the last line
 
S

Samuel Kleiner

Bengt said:
First please explain why you are trying to do whatever it is you're trying to do ;-)

I was trying to automatically extend M to cover all binary operators not
covered by dict, preferably without assigning to them all.

class M(dict):
def __add__(self, add):
if type(add) in self:
self[type(add)]=self[type(add)]+add
else:
self[type(add)]=add
return self

def __str__(self):
return "+".join(map(str,self.values()))

print M()+"foo"+2+"bar"+5
Out:
foobar+7
I doubt if that's the first problem ;-)

Yes, I was jetlagged. new.instancemethod seems the way to go, really.
 
B

Bengt Richter

I haven't a clue what you're trying to do, but
I believe it's not possible to install "magic methods"
after the class is defined. Nor can you install
them in the instance. They'll look like they've
been installed, but the interpreter will never
execute them because it does not look there
for them. It looks in special places in the C
language structure for the class definition.
I'm not sure what you mean about not installing methods, but methods
are effectively dynamically created when you access functions via a
class attribute name, so you can tack them on any time before you
access them. If you access them via a class attribute per se, you get
an unbound method, and if you access them via a class instance, you get
a bound (to that instance) method. E.g.,
'This is from a method of B'

Note the distiction between 'foo' and 'method_name'. Once 'foo' has been used to
create the method, only the name of the function is available via the (un)bound method
object reference. They happen to match when you do the def inside the class scope, but
they don't have to, though the repr string might be a little confusing when they don't.

If you use a programming trick to get the function bound as an attribute of a class,
that should work just like doing it explicitly as above.

Note that the unbound method is not just a reference to the function:
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: unbound method method_name() must be called with A instance as first argument (got B
instance instead)

Though you can sneak around to it:
<function method_name at 0x008FDE70>

And it happens to work as a function 'This is from a method of B'

To get that function we see via A to be an unbound method of B is also possible:
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: unbound method method_name() must be called with B instance as first argument (got A
instance instead)

Regards,
Bengt Richter
 
A

Alex Martelli

John said:
I haven't a clue what you're trying to do, but
I believe it's not possible to install "magic methods"
after the class is defined. Nor can you install
them in the instance. They'll look like they've

It's true that (with newtype classes) special methods
can't be usefully "installed in the instance", but it's
not true that they can't usefully be "installed after
the class is defined" (as long as they ARE installed in
the _class_, not in the _instance_).

For example:

Here we see that the first attempt, "installing in
the instance" in your terminology, was inoperative; but
the second one, "installing in the class" even though
well after the class was defined was perfectly operative
(on existing instances of the class, too -- of course it
also works just fine on any further new instance you may
create thereafter).
been installed, but the interpreter will never
execute them because it does not look there
for them. It looks in special places in the C
language structure for the class definition.

Yes, but the C code does go to the trouble of updating
those special places when you change the _class_ (NOT
when you change the instance).


If you want to add what amounts to a "per-instance
special method" you have, in practice, to make the
instance's class unique. There are several ways to
do that, including on-the-fly and (better if you do
know all instances of a certain class will need such
treatment) in a __new__ method on the common baseclass.

I'm not sure what, exactly, the OP was trying to do
in his example code, but perhaps it can be accomplished
by the "give each instance a unique class" (and change
that class, when you want to "install special methods")
approach.


Alex
 
S

Shalabh Chaturvedi

Alex said:
It's true that (with newtype classes) special methods
can't be usefully "installed in the instance", but it's
not true that they can't usefully be "installed after
the class is defined" (as long as they ARE installed in
the _class_, not in the _instance_).

For example:



I am an X


Here we see that the first attempt, "installing in
the instance" in your terminology, was inoperative; but
the second one, "installing in the class" even though
well after the class was defined was perfectly operative
(on existing instances of the class, too -- of course it
also works just fine on any further new instance you may
create thereafter).

If you want to add what amounts to a "per-instance
special method" you have, in practice, to make the
instance's class unique. There are several ways to
do that, including on-the-fly and (better if you do
know all instances of a certain class will need such
treatment) in a __new__ method on the common baseclass.

<snip>

Another option might be to use a descriptor on the class that looks up
an instance attribute. A simplified example:
.... def __init__(self, ipropname):
.... self.ipropname = ipropname
.... def __get__(self, ob, cls):
.... if ob is not None and ob.__dict__.has_key(self.ipropname):
.... return ob.__dict__[self.ipropname]
....
Any downside to this one?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top