In a nutshell:
What is the equivalent of __radd__ (wich overloads the right hand side
of +) when overloading the comparison operators <,>,== and so on. My
first guess __rlt__ for
overloading the rigth hand side of < did not work.
Expanded version:
In a class of numbers I have been able to overload the four arithmetic
operators +,-,* and / by defining the methods __add__ and __radd__
(etc..) in my class. This enables me to evaluate expressions
"instance_of_my _class+"instanc e_of_my_class" ,"instance + non_instance"
(with __add__) as well as "non_instance+i nstance"(with __radd__).
But my guess to define the method __rlt__ in my class in order to be
able to evaluate expressions "non_instan ce < instance" did not work.
So what are the names (if they exist at all) of the comparison operators
<,>,== and so on, when one wants to exend their rigth hand side to a
user defined (instance of a) class?
In case of direct e-mail response please remove the french translation
of nospam in my signature, that is to say the string :
pasdepourriels. 13 2010
denis wendum <we**********@p asdepourriels.e df.fr> wrote: But my guess to define the method __rlt__ in my class in order to be able to evaluate expressions "non_instan ce < instance" did not work.
Sensible guess, but not the way things work.
So what are the names (if they exist at all) of the comparison operators <,>,== and so on, when one wants to exend their rigth hand side to a user defined (instance of a) class?
Here's how to find out: class foo:
.... def __getattr__(sel f, name):
.... print 'looking for %r' % name
.... raise AttributeError, name
.... f=foo() 12 < f
looking for '__gt__'
looking for '__coerce__'
looking for '__cmp__'
True
See what's happening here? After determining that int (the type of 12)
cannot deal with comparing 12 with an instance of foo, Python's
implementation of < turns to the right hand side... and asks for a
__gt__ method first! Makes sense, because 12 < f is presumably going to
be the same thing as f > 12 ... once it doesn't find __gt__ the
implementation continues by trying to coerce f to an int (by checking if
class foo supports __coerce__) and lastly by trying for the old-style
comparison method __cmp__. But you presumably don't care about that;
rather, the gist of it is: write your __gt__ -- that will also be used
as your "__rlt__" -- and so on!
Alex
On Tue, 12 Oct 2004 16:06:52 +0200, al*****@yahoo.c om (Alex Martelli) wrote: denis wendum <we**********@p asdepourriels.e df.fr> wrote:
But my guess to define the method __rlt__ in my class in order to be able to evaluate expressions "non_instan ce < instance" did not work.
Sensible guess, but not the way things work.
So what are the names (if they exist at all) of the comparison operators <,>,== and so on, when one wants to exend their rigth hand side to a user defined (instance of a) class?
Here's how to find out:
class foo:... def __getattr__(sel f, name): ... print 'looking for %r' % name ... raise AttributeError, name ... f=foo() 12 < flooking for '__gt__' looking for '__coerce__' looking for '__cmp__' True See what's happening here? After determining that int (the type of 12) cannot deal with comparing 12 with an instance of foo, Python's implementati on of < turns to the right hand side... and asks for a __gt__ method first! Makes sense, because 12 < f is presumably going to be the same thing as f > 12 ... once it doesn't find __gt__ the implementati on continues by trying to coerce f to an int (by checking if class foo supports __coerce__) and lastly by trying for the old-style comparison method __cmp__. But you presumably don't care about that; rather, the gist of it is: write your __gt__ -- that will also be used as your "__rlt__" -- and so on!
On my system, (NT4, python 2.3.2) what really happens for newstyle classes
isn't apparent from that experiment: class foo(object):
... def __getattr__(sel f, name):
... print 'looking for %r' % name
... raise AttributeError, name
... f=foo() 12 < f
True
The old style does work much the same (but note the default end result ;-)
Is that a 2.3.2 bug?
class foo:
... def __getattr__(sel f, name):
... print 'looking for %r' % name
... raise AttributeError, name
... f=foo() 12 < f
looking for '__gt__'
looking for '__coerce__'
looking for '__cmp__'
False
Regards,
Bengt Richter
I think it's a difference in new-style classes that __getattr__ doesn't
have a chance to run when searching for special methods.
I'm sure this is documented, but I didn't see it in http://python.org/2.2.2/descrintro.html
Jeff
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)
iD8DBQFBbIUEJd0 1MZaTXX0RAgC4AJ 9VDc64p8uTr+2Rq IjDqs/wjdcN4wCgiGBs
iyu6fjYUTutHsSO BvTFE1ds=
=Cnor
-----END PGP SIGNATURE-----
Bengt Richter <bo**@oz.net> wrote:
... > class foo:... def __getattr__(sel f, name):
... On my system, (NT4, python 2.3.2) what really happens for newstyle classes isn't apparent from that experiment:
Heh, of course not -- the main difference between old-style and
new-style classes is that, for the latter, implicit lookup of special
methods when needed for operations starts with the *class*, not with the
*instance*. This is a fix of a long-standing design bug, because the
old rule was just impossible to apply consistently -- if calling X meant
looking for X.__call__ rather than X.__class__.__c all__, how could you
ever instantiate X by calling it, when X is a class whose _instances_
are meant to be callable, for example?
Since this has been discussed many times on this group, as well as in
presentations, articles, websites, books, ..., I didn't think it was
necessary to dwell on the issue again, considering it really did not
affect the answer requested by the original poster; apparently I was
wrong in so thinking. _Sigh_ -- next time somebody criticizes my posts
as being too long, I'll retort that of course they are, if I must keep
repeating such issues!-)
I just used an old-style class because, that way, I could show the
lookups happening without having to code a custom metaclass. The
special names being looked for are just the same, whether for classic or
newstyle classes, anyway -- all that changes is _where_ they're looked
up (starting on the instance, vs starting on the class). >>> class foo(object): ... def __getattr__(sel f, name): ... print 'looking for %r' % name ... raise AttributeError, name ... >>> f=foo() >>> 12 < f
True
The old style does work much the same (but note the default end result ;-) Is that a 2.3.2 bug?
No bug: comparisons between objects of disparate types give essentially
arbitrary results (repeatable within one run, but, at least in theory,
potentially different among runs of the same program, I believe).
Alex
On Wed, 13 Oct 2004 10:18:28 +0200, al*****@yahoo.c om (Alex Martelli) wrote: Bengt Richter <bo**@oz.net> wrote: ... >>>> class foo: >... def __getattr__(sel f, name): ... On my system, (NT4, python 2.3.2) what really happens for newstyle classes isn't apparent from that experiment: Heh, of course not -- the main difference between old-style and new-style classes is that, for the latter, implicit lookup of special methods when needed for operations starts with the *class*, not with the
Well, it always starts with the class if there's no attribute on the instance,
but the key is whether the "implicit lookup" for methods needed for operations
uses an overridable __getattribute_ _ somewhere, or just chases down the bases
chain looking for the actual __gt__ or whatever, not allowing a hook to synthesize
a result.*instance*. This is a fix of a long-standing design bug, because the old rule was just impossible to apply consistently -- if calling X meant looking for X.__call__ rather than X.__class__.__c all__, how could you ever instantiate X by calling it, when X is a class whose _instances_ are meant to be callable, for example?
Since this has been discussed many times on this group, as well as in presentation s, articles, websites, books, ..., I didn't think it was necessary to dwell on the issue again, considering it really did not affect the answer requested by the original poster; apparently I was wrong in so thinking. _Sigh_ -- next time somebody criticizes my posts as being too long, I'll retort that of course they are, if I must keep repeating such issues!-)
I have suspected you of having voice recognition input ;-)
I don't type that fast, unfortunately.
I just used an old-style class because, that way, I could show the lookups happening without having to code a custom metaclass. The
Could you show such a metaclass? I have tried a few things and not succeeded.
It almost makes me think there is no place to hook the internal __getattribute_ _
that looks for the methods for code generated from 12<f and the like.
I'd be interested in seeing it.
special names being looked for are just the same, whether for classic or
^^^^^^^^^^^^^^ but maybe not the same order, see belownewstyle classes, anyway -- all that changes is _where_ they're looked up (starting on the instance, vs starting on the class).
>>> class foo(object): ... def __getattr__(sel f, name): ... print 'looking for %r' % name ... raise AttributeError, name ... >>> f=foo() >>> 12 < f True
The old style does work much the same (but note the default end result ;-) Is that a 2.3.2 bug?
No bug: comparisons between objects of disparate types give essentially arbitrary results (repeatable within one run, but, at least in theory, potentially different among runs of the same program, I believe).
I tried a class with all the methods explicit, and then removed them: class foo(object):
... def __gt__(self, other): print 'gt'
... def __coerce__(self , other): print 'coerce'
... def __cmp__(self, other): print 'cmp'
... f=foo() 12<f
gt
Ok, so it looked for __gt__ first. Remove that. del foo.__gt__
12<f
cmp
It seems to have looked for __cmp__ second, unlike in your post:
+---<from your post>------------------
Here's how to find out:
class foo:
.... def __getattr__(sel f, name):
.... print 'looking for %r' % name
.... raise AttributeError, name
.... f=foo() 12 < f
looking for '__gt__'
looking for '__coerce__'
looking for '__cmp__'
True
+-------------------------------------
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: an integer is required
(didn't like none back from cmp, presumably)
Ok, remove __cmp__ del foo.__cmp__
One left: 12<f
coerce
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: __coerce__ didn't return a 2-tuple
NBD, but perhaps the order change is a version difference?
Not that the OP was asking any of this ;-)
Regards,
Bengt Richter
Bengt Richter <bo**@oz.net> wrote: On Wed, 13 Oct 2004 10:18:28 +0200, al*****@yahoo.c om (Alex Martelli) wrote:
Bengt Richter <bo**@oz.net> wrote: ... >>>> class foo: >... def __getattr__(sel f, name): ... On my system, (NT4, python 2.3.2) what really happens for newstyle classes isn't apparent from that experiment:
Heh, of course not -- the main difference between old-style and new-style classes is that, for the latter, implicit lookup of special methods when needed for operations starts with the *class*, not with the Well, it always starts with the class if there's no attribute on the instance,
I find this a strange meaning for the word "start". To ensure the
instance doesn't have the attribute, that's where (conceptually) one
could say the lookup "starts", I think.
but the key is whether the "implicit lookup" for methods needed for operations uses an overridable __getattribute_ _ somewhere, or just chases down the bases chain looking for the actual __gt__ or whatever, not allowing a hook to synthesize a result.
Actually, it reaches right into the appropriate slot of the type
structure. The slots are generated or changed when the type (i.e., the
class object) is generated or changed. So, it may be improper on my
part to call this procedure a 'lookup'. I just used an old-style class because, that way, I could show the lookups happening without having to code a custom metaclass. The Could you show such a metaclass? I have tried a few things and not succeeded. It almost makes me think there is no place to hook the internal __getattribute_ _ that looks for the methods for code generated from 12<f and the like. I'd be interested in seeing it.
I think I'd basically have to repeat what types.ClassType is doing --
essentially, prefill all slots with functions that _do_ perform the
lookups. To be honest, I haven't tried to see if that strategy hits any
snags, I just don't think it would. special names being looked for are just the same, whether for classic or ^^^^^^^^^^^^^^ but maybe not the same order, see belownewstyle classes, anyway -- all that changes is _where_ they're looked up (starting on the instance, vs starting on the class).
You're right -- coercion is "fading" so it's now attempted _after_ 3-way
comparison rather than before; so the 'where' isn't quite _all_ that's
changed (I had never coded nor seen a classic class which depended on
coercion for its comparisons, which may explain though not excuse my
imprecision).
NBD, but perhaps the order change is a version difference?
Yep, it's part of coercion slowly going away.
Not that the OP was asking any of this ;-)
No, but they may still be meaningful in some cases, of course.
Alex
On Wed, 13 Oct 2004 10:52:57 GMT, bo**@oz.net (Bengt Richter) wrote:
[...] NBD, but perhaps the order change is a version difference? Not that the OP was asking any of this ;-)
Posted before recalling that the order difference showed up
on my system between old-style and new-style, both on 2.3.2,
so at least what I saw is not a version difference.
Someplace in classobject vs typeobject or such?
Regards,
Bengt Richter
Alex Martelli a écrit : denis wendum <we**********@p asdepourriels.e df.fr> wrote: Here's how to find out:
class foo: ... def __getattr__(sel f, name): ... print 'looking for %r' % name ... raise AttributeError, name ... f=foo() 12 < f looking for '__gt__' looking for '__coerce__' looking for '__cmp__' True
See what's happening here?
Alex
Many thanks for your answer: you didn't just gave me the fish I asked but also
showed me how to use a net for catching other fish.
It seems I triggered a fierce debate with my question, but as far as I'm
concerned your example worked perfectly.
denis wendum <we**********@p asdepourriels.e df.fr> wrote:
... Here's how to find out:
>> class foo: ... def __getattr__(sel f, name): ... print 'looking for %r' % name ... raise AttributeError, name ...>> f=foo() >> 12 < f looking for '__gt__' looking for '__coerce__' looking for '__cmp__'
... Many thanks for your answer: you didn't just gave me the fish I asked but also showed me how to use a net for catching other fish.
You're welcome! Python enjoys excellent "discoverabilit y" (a term
copiously illustrated, by explanation and by example, in Eric Raymond's
excellent book "The Art of Unix Programming", highly recommended in both
paper and free-on-the-net form) -- it shews enough of its workings,
easily enough, that it's well worth doing some sniffing around, and the
ability to hack together a 4-line class that displays things with some
print statements in an interactive session is a good example.
Of course, I _was_ being a tad too glib here, which helps explain...:
It seems I triggered a fierce debate with my question, but as far as I'm concerned your example worked perfectly.
....the "debate", which was in fact quite friendly, even for this
community's pretty good standards. Summarizing, I half-cheated by using
an oldstyle class here, so that __getattr__ would indeed get called; a
newstyle class, while having just about the same behavior, does (...to
oversimply things a bit...) more processing at the time the class
statement is executed, it fills up a structure of internal 'slots', so
there is less "rooting around" at the time the < operator executes and
less of a chance to see the wheels in motion (there are of course plenty
of advantages in exchange, both conceptual and practical). Moreover the
'__coerce__' concept is being de-emphasized and deprecated, so the
"lookup" order shifts slightly (coercion is now tried only as a "last
ditch", after 3-way comparison with __cmp__ rather than before).
This doesn't mean you can't do "sniffing around" in newstyle classes,
but it may require a different tack, such as: class foo(object):
.... def __gt__(self, other):
.... print 'doing gt'
.... return NotImplemented
.... def __cmp__(self, other):
.... print 'doing cmp'
.... return NotImplemented
.... f=foo() 2<f
doing gt
doing cmp
False
The "return NotImplemented" may be seen as a way to implement a specific
comparison (say __gt__) in some cases while punting to more generic ways
implicitly -- you may use it to indicate to Python "I don't know how to
do this specific comparison in this specific method, so please try
something else [along the usual orders in which things are tried]"...
Alex This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: bq |
last post by:
Hello,
This post is really two questions.
Question 1:
What is the current status on a revision of ISO C++, specifically
regarding plans for overloading composite operators? Some people in
this group probably would know. By "overloading composite operators" I
mean conversion of an expression like
A = B * C;
into a single function call (instead of three calls; one to "*",
another to copy and another to "="). Here A, B and C are of a
|
by: KL |
last post by:
I am working on a school assignment, so please don't tell me the
solution. I just want some direction.
I am supposed to overload the >, <, ==, !=, >=, and <= operators using
bool. I am having a bit of a problem in seeing what needs to happen
here. I am just not sure how I do this. Will the overloading function
recognize a < and a usual <? Do I do an
IF (a.letters < b.letters){
return true
}
|
by: Jerry Fleming |
last post by:
As I am newbie to C++, I am confused by the overloading issues. Everyone
says that the four operators can only be overloaded with class member
functions instead of global (friend) functions: (), , ->, =. I wonder
why there is such a restriction.
Some tutorials say that 'new' and 'delete' can only be overloaded with
static member functions, others say that all overloading function should
be non-static. Then what is the fact, and why?
...
|
by: josh |
last post by:
Hi, I coded the following but It does not return what I expect, why?
#include <iostream>
using namespace std;
class Other
{
public:
int i;
|
by: johnmmcparland |
last post by:
Hi all,
I know it is possible to overload the operators and < in C++ but how
can I do this.
Assume I have a class Date with three int members, m_day, m_month and
m_year. In the .cpp files I have defined the < and operators;
bool Date::operator<(const Date& d)
{
| |
by: PengYu.UT |
last post by:
Hi,
It seems that C++ does not allow overloading operators for primative
types, e.g. int, double. I'm wondering whether it is ture or there is
some walk-around?
Thanks,
Peng
#include <iostream>
|
by: Wayne Shu |
last post by:
Hi everyone, I am reading B.S. 's TC++PL (special edition).
When I read chapter 11 Operator Overloading, I have two questions.
1. In subsection 11.2.2 paragraph 1, B.S. wrote "In particular,
operator =, operator, operator(), and operator-must be nonstatic
member function; this ensures that their first operands will be
lvalues". I know that these operators must be nonstatic member
functions, but why this ensure their first operands will...
|
by: Rahul |
last post by:
Hi Everyone,
I was overloading the operator= function as a class member function,
#include <iostream.h>
class A
{
int value;
public : A& operator = (const A& ref)
|
by: jimzat |
last post by:
I am trying to simulate the execution of some PLC ladder logic in
python.
I manually modified the rungs and executed this within python as a
proof of concept, but I'd like to be able to skip the modification
step. My thought was that this might be able to be completed via
overloading, but I am not sure if (or how) it could be done.
overloadings:
+ ==OR
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it.
First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
| |
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own....
Now, this would greatly impact the work of software developers. The idea...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
| |
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |