473,396 Members | 2,129 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,396 software developers and data experts.

Can a base class know if a method has been overridden?

Hi all,

I was wondering if something like this is possible. Can a base class
somehow know if a certain method has been overridden by the subclass?
I appreciate any ideas.
Thanks,

Ratko

Sep 24 '07 #1
12 4829
Ratko a écrit :
Hi all,

I was wondering if something like this is possible. Can a base class
somehow know if a certain method has been overridden by the subclass?
If your use case is to make sure a given ('abstract') method has been
overriden, the canonical solution is to raise NotImplementedError in the
base class's implementation, ie:
class Parent(object):
def method(self):
raise NotImplementedError

class GoodGirl(Parent):
def method(self):
print "I'm a good girl"

class BadBoy(Parent):
pass
Else, this may be possible using a custom metaclass (or possibly just
specializing the __new__ method), but there may be better solutions
(depending on what you're really trying to do)..

HTH
Sep 24 '07 #2
On Sep 24, 5:23 pm, Ratko <rjago...@gmail.comwrote:
Hi all,

I was wondering if something like this is possible. Can a base class
somehow know if a certain method has been overridden by the subclass?
I appreciate any ideas.
Thanks,

Ratko

The first time I used Zope, I immediately had an issue of overriding a
predefined
methods without knowing it (there were 400+ methods inherited from
dozens of base
classes). So I wrote this utility:
def check_if_I_am_overriding_names():
"""Prints a message if we are overriding a name. Useful for
framework
beginners. Example in Zope:
>from OFS.Folder import Folder
class MyFolder(OFS.Folder):
.. check_if_I_am_overriding_names()
.. id = 'pippo'
..
AlreadyDefinedNameWarning: id
"""

def makecls(name, bases, dic):
for nam, val in dic.iteritems():
if nam.endswith("__") or nam == "meta_types":
# ignore redefinitions of special names
# and redefinition of meta_types (for Zope code)
continue
any_base_has_name = [base for base in bases
if hasattr(base, nam)]
if any_base_has_name:
print "AlreadyDefinedNameWarning: " + nam
return type(name, bases, dic)

f = sys._getframe(1)
f.f_locals["__metaclass__"] = makecls

Michele Simionato

Sep 24 '07 #3
If your use case is to make sure a given ('abstract') method has been
overriden, the canonical solution is to raise NotImplementedError in the
base class's implementation
I am not really interested in forcing the subclass to implement a
method. I am interested in knowing *whether* it did implement it or
not.

Else, this may be possible using a custom metaclass (or possibly just
specializing the __new__ method), but there may be better solutions
(depending on what you're really trying to do)..
I have a base class EvtHandler that has methods defined to handle
certain events. You then subclass from EvtHandler and override the
methods for the events you want to receive. If a method has been
overridden, the base class will automatically register for those
events to make sure that they are even delivered to this handler
(which is why I would need to know whether a method has been
overridden or not). Of course, there are other ways of doing this
which would require a bit more work from the subclass... I just
thought this would be a neat "automatic" way of registering for
events.

For example:

class EvtHandler:
def __init__(self):
if onKey is overridden:
register_for_key_events()

def onKey(self):
pass
class MyHandler(EvtHandler):
def onKey(self):
# do something here....

Sep 24 '07 #4
On Mon, 24 Sep 2007 15:48:07 +0000, Ratko wrote:
I have a base class EvtHandler that has methods defined to handle
certain events. You then subclass from EvtHandler and override the
methods for the events you want to receive. If a method has been
overridden, the base class will automatically register for those
events to make sure that they are even delivered to this handler
(which is why I would need to know whether a method has been
overridden or not). Of course, there are other ways of doing this
which would require a bit more work from the subclass... I just
thought this would be a neat "automatic" way of registering for
events.

For example:

class EvtHandler:
def __init__(self):
if onKey is overridden:
register_for_key_events()

def onKey(self):
pass
class MyHandler(EvtHandler):
def onKey(self):
# do something here....
Maybe "tagging" the original `on_key()`:

class EvtHandler:
def __init__(self):
if not hasattr(self.on_key, 'dummy'):
print 'register_for_key_events()'

def _dummy_handler(self):
pass
_dummy_handler.dummy = True

on_key = _dummy_handler
on_whatever = _dummy_handler
class MyHandler(EvtHandler):
def on_key(self):
print 'Do something...'

Ciao,
Marc 'BlackJack' Rintsch
Sep 24 '07 #5
On 9/24/07, Ratko <rj******@gmail.comwrote:
If your use case is to make sure a given ('abstract') method has been
overriden, the canonical solution is to raise NotImplementedError in the
base class's implementation

I am not really interested in forcing the subclass to implement a
method. I am interested in knowing *whether* it did implement it or
not.

Else, this may be possible using a custom metaclass (or possibly just
specializing the __new__ method), but there may be better solutions
(depending on what you're really trying to do)..

I have a base class EvtHandler that has methods defined to handle
certain events. You then subclass from EvtHandler and override the
methods for the events you want to receive. If a method has been
overridden, the base class will automatically register for those
events to make sure that they are even delivered to this handler
(which is why I would need to know whether a method has been
overridden or not). Of course, there are other ways of doing this
which would require a bit more work from the subclass... I just
thought this would be a neat "automatic" way of registering for
events.

For example:

class EvtHandler:
def __init__(self):
if onKey is overridden:
register_for_key_events()

def onKey(self):
pass
class MyHandler(EvtHandler):
def onKey(self):
# do something here....
Clumsy, but it seems to work. Using a sentinel value as Marc Rintsch
suggests might be better:
>>class A(object):
.... def vMethod(self, x):
.... raise NotImplemented
.... def is_implemented(self, method):
.... if getattr(type(self), method.__name__).im_func is not
method.im_func:
.... return True
.... def otherMethod(self, x):
.... raise NotImplemented
....
>>class B(A):
.... def vMethod(self, x):
.... print x
....
>>b = b()
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: 'B' object is not callable
>>b = B()
b.otherMethod(10)
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "<input>", line 8, in otherMethod
TypeError: exceptions must be classes, instances, or strings
(deprecated), not NotImplementedType
>>b.vMethod(10)
10
>>b.is_implemented(A.vMethod)
True
>>b.is_implemented(A.otherMethod)

(Note that I accidentally raised NotImplemented instead of
NotImplementedError, oops.)
Sep 24 '07 #6
Ratko a écrit :
>If your use case is to make sure a given ('abstract') method has been
overriden, the canonical solution is to raise NotImplementedError in the
base class's implementation

I am not really interested in forcing the subclass to implement a
method. I am interested in knowing *whether* it did implement it or
not.

>Else, this may be possible using a custom metaclass (or possibly just
specializing the __new__ method), but there may be better solutions
(depending on what you're really trying to do)..

I have a base class EvtHandler that has methods defined to handle
certain events. You then subclass from EvtHandler and override the
methods for the events you want to receive. If a method has been
overridden, the base class will automatically register for those
events to make sure that they are even delivered to this handler
(which is why I would need to know whether a method has been
overridden or not). Of course, there are other ways of doing this
which would require a bit more work from the subclass... I just
thought this would be a neat "automatic" way of registering for
events.

For example:

class EvtHandler:
def __init__(self):
if onKey is overridden:
register_for_key_events()

def onKey(self):
pass
class MyHandler(EvtHandler):
def onKey(self):
# do something here....
Ok. The simplest solution, then, is simply to not implement the method
in the base class, ie:

class EvtHandler:
def __init__(self):
if hasattr(self, 'onKey'):
register_for_key_events()

#def onKey(self):
# pass
class MyHandler(EvtHandler):
def onKey(self):
# do something here....
Another solution is to compare the functions wrapped by the methods:

class EvtHandler:
def __init__(self):
onKey = getattr(self, 'onKey')
if onKey.im_func is EvtHandler.onKey.im_func:
register_for_key_events()

def onKey(self):
pass
class MyHandler(EvtHandler):
def onKey(self):
# do something here....
HTH
Sep 24 '07 #7
What about something like:

class A(object):
def my_method(self):
print "A.my_method"
def call_my_method(self):
if type(self).my_method == A.my_method:
print "Calling base class method."
else:
print "Calling derived class method."
self.my_method()

class B(A):
pass

class C(A):
def my_method(self):
print "C.my_method"

a = A()
b = B()
c = C()

a.call_my_method()
b.call_my_method()
c.call_my_method()
Stéphane

Sep 24 '07 #8
Ok. The simplest solution, then, is simply to not implement the method
in the base class, ie:

class EvtHandler:
def __init__(self):
if hasattr(self, 'onKey'):
register_for_key_events()

#def onKey(self):
# pass

class MyHandler(EvtHandler):
def onKey(self):
# do something here....

Another solution is to compare the functions wrapped by the methods:

class EvtHandler:
def __init__(self):
onKey = getattr(self, 'onKey')
if onKey.im_func is EvtHandler.onKey.im_func:
register_for_key_events()

def onKey(self):
pass

class MyHandler(EvtHandler):
def onKey(self):
# do something here....

HTH
The second solution works beautifully! Thank you very much.
I was aware that not implementing the onKey method in the first place
is the simplest solution but it's much cleaner to offer the methods in
advance so that the user can see what is possible.

Ratko

Sep 24 '07 #9
On Sep 24, 12:56 pm, Stéphane Larouche <stephane.larou...@polymtl.ca>
wrote:
What about something like:

class A(object):
def my_method(self):
print "A.my_method"
def call_my_method(self):
if type(self).my_method == A.my_method:
print "Calling base class method."
else:
print "Calling derived class method."
self.my_method()

class B(A):
pass

class C(A):
def my_method(self):
print "C.my_method"

a = A()
b = B()
c = C()

a.call_my_method()
b.call_my_method()
c.call_my_method()

Stéphane

I think it would confuse the user to have to call "call_my_method" as
opposed to calling "my_method" directly. The only reason why I wanted
to do this is simplicity, clarity and transparency. Thanks though.
Bruno's solution does exactly what I was looking for.

Ratko

Sep 24 '07 #10
Ratko wrote:
I was wondering if something like this is possible. Can a base class
somehow know if a certain method has been overridden by the subclass?
You can try using the __subclasses__() method on the class::
>>def is_overridden(method):
... for cls in method.im_class.__subclasses__():
... func = cls.__dict__.get(method.__name__)
... if func is not None and func != method.im_func:
... return True
... return False
...
>>class A(object):
... def foo(self):
... return 'A.foo'
... def bar(self):
... return 'A.bar'
...
>>class B(A):
... def foo(self):
... return 'B.foo'
...
>>is_overridden(A.foo)
True
>>is_overridden(A.bar)
False

Given a method from the base class, is_overridden gets the base class,
and then looks through every subclass of that class. If the function
object for the subclass is ever different from that of the base class,
then the base class's method must have been overridden.

STeVe
Sep 24 '07 #11
On Sep 24, 8:23 am, Ratko <rjago...@gmail.comwrote:
Hi all,

I was wondering if something like this is possible. Can a base class
somehow know if a certain method has been overridden by the subclass?
I appreciate any ideas.
Thanks,

Ratko

It's not hard. Both bound and unbound methods have an im_func
attribute pointing to the underlying function code. So you can check
for overrides by testing whether the underlying functions are the
same:
>>class A:
def p(self): pass
def q(self): pass

>>class B(A):
def q(self): pass

>>b = B()
b.p.im_func is A.p.im_func # Verify that b.p runs A.p
True
>>b.q.im_func is A.q.im_func # Verify that b.q overrides A.q


Raymond

False

Sep 24 '07 #12
Ratko a écrit :
bruno a écrit
>>Another solution is to compare the functions wrapped by the methods:

class EvtHandler:
def __init__(self):
onKey = getattr(self, 'onKey')
if onKey.im_func is EvtHandler.onKey.im_func:
s/is/is not/, of course
> register_for_key_events()

def onKey(self):
pass

class MyHandler(EvtHandler):
def onKey(self):
# do something here....

HTH


The second solution works beautifully!
Hem... Almost !-)
Thank you very much.
I was aware that not implementing the onKey method in the first place
is the simplest solution but it's much cleaner to offer the methods in
advance so that the user can see what is possible.
Yeps - a placeholder 'abstract' method with only a docstring. It's a
common pattern in frameworks, but usually it's just an ordinary template
method pattern defaulting to a no-op.

FWIW, if you have several such methods to handle, you can use a more
generic approach:

_handlers = {
'onKey':registerForKeyEvents,
'onClick':registerForMouseEvents,
} # etc

class EventHandler(object):
for _name in _handlers:
exec "%s=lambda self, *args, **kw: pass" % _name

def __new__(cls, *args, **kw):
obj = object.__new__(cls, *args, **kw)
for name, register_func in _handlers.items():
meth = getattr(obj, name)
dummy = getattr(EventHandler, name)
if meth.im_func is not dummy.im_func:
register_func(meth)
return obj
HTH
Sep 25 '07 #13

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

Similar topics

6
by: Daniel Billingsley | last post by:
I understand the conditions where you have to use base., but does it make any sense to use it elsewhere to make clear to the reader that the method or property you refer to comes from the base...
5
by: Dave Veeneman | last post by:
I'm using inheritance more than I used to, and I find myself calling a lot of base class methods. I generally call a base method from a dreived class like this: this.MyMethod(); I'm finding...
4
by: Akhil | last post by:
Hi All, Can u please explain this. Base Obj = new Derived(); Can Obj access methods both of Base and Derived or what will be the behaviour? What will be the behaviour for Overridden...
3
by: martin | last post by:
Hi, If I have a base class, say called "MyBase" and a derived class called "Myderived" is it possible to get the name of the derived class from the base class fo example if I have a method in...
5
by: Andy | last post by:
Hi all, I have a site with the following architecture: Common.Web.dll - Contains a CommonPageBase class which inherits System.Web.UI.Page myadd.dll - Contains PageBase which inherits...
4
by: Ray Dukes | last post by:
What I am looking to do is map the implementation of interface properties and functions to an inherited method of the base class. Please see below. ...
7
by: relient | last post by:
Question: Why can't you access a private inherited field from a base class in a derived class? I have a *theory* of how this works, of which, I'm not completely sure of but makes logical sense to...
3
by: Rick | last post by:
One of the rules I have recommended for our new coding standard is as follows: "When overriding a base class virtual function, all overloads of that base class virtual function should also be...
1
by: nsphelt | last post by:
I am wondering if it is possible to access the underlying property of a base class within a derived that has overridden that property. I am using VB.NET and when I use the MyBase keyword to access...
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: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
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...
0
Oralloy
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,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
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...
0
agi2029
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,...

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.