Erik Jones
Software Developer | Emma®
er...@myemma.com
800.595.4401 or 615.292.5888
615.292.0777 (fax)
Emma helps organizations everywhere communicate & market in style.
Visit us online at http://www.myemma.com
You look if the method was defined in self.__class__.__dict__.
Michele Simionato
That doesn't seem to cover calling super class __init__ methods.
I am probably missing something. In the following code the
method check_init checks if the current instance
possess an __init__ or if it just inherits one
from the ancestors. Is this what you want?
class B(object):
def __init__(self):
'something'
def check_init(self):
if '__init__' in self.__class__.__dict__:
print 'possesses __init__'
else:
print 'inherits __init__'
class C(B):
'something else'
def __init__(self):
print 'calling C.__init__'
class D(B):
pass
c = C()
d = D()
c.check_init() #possesses __init__
d.check_init() #inherits __init__
Ok, I see how I was pretty vague with my original questions. Given
the pattern where you need to call a base class's constructor (or,
other overriden method of the same name as that being called on the
child class object):
class A(object):
def __init__(self):
print self.__class__.__name__
class B(A):
def __init__(self):
A.__init__(self)
print self.__class__.__name__
B()
This will output:
B
B
How can I get
A
B
> Ok, I see how I was pretty vague with my original questions.
> Given the pattern where you need to call a base class's constructor
> (or, other overriden method of the same name as that being called
> on the child class object):
>
> class A(object):
> def __init__(self):
> print self.__class__.__name__
>
> class B(A):
> def __init__(self):
> A.__init__(self)
> print self.__class__.__name__
>
> B()
>
> This will output:
>
> B
> B
>
> How can I get
>
> A
> B
Perhaps an even better example of what I'm trying to do would be in
order (this is minus any exception handling):
import sys
def mytrace(frame, event, arg):
if event == 'call':
func_name = frame.f_code.co_name
if func_name in frame.f_locals['self'].__class__.__dict__:
print frame.f_locals['self'].__class__.__name__
else:
for base in frame.f_locals['self'].__class__.__bases__:
if func_name in base.__dict__:
print base.__name__
break
class A(object):
def __init__(self):
pass
class B(A):
def __init__(self):
A.__init__(self)
sys.settrace(mytrace)
B()
This will output:
B
B
whereas I'm shooting for:
B
A
If you don't mind post-processing the results, you can log the function
name and source module (from frame.f_code.co_name and co_filename) and
current line number (frame.f_lineno). Later, obtaining the class name from
those is a bit tricky (and not even the inspect module does it right), but
perhaps using the tokenizer module, watching for lines that contain
"class" <name> is enough.
--
Gabriel Genellina
I was afraid of that. I used pretty much that tokenizer trick for a
unit test generator I wrote in php a while back and felt like that
was pretty clunky then.
Hacky, but maybe this will work:
import sys
import inspect
def mytrace(frame, event, arg):
if event == 'call':
func_name = frame.f_code.co_name
klassOb = frame.f_locals['self'].__class__
for klass in inspect.getmro(klassOb):
cf = klass.__dict__.get(func_name)
if hasattr(cf, "func_code") and cf.func_code == frame.f_code:
print klass.__name__
Chris, that is absolutely perfect. Also, I don't think there is such
a thing as profiling code that isn't hacky ;)