introspection inquiry

M

mirandacascade

Where in the language would one find the intropsection capability to
answer the question: what class am I in?

Example:

class ExistentialCrisis:
def __init__(self, text):
self.spam = text
print 'In the constructor of the %s class' % <whatever>

When the constructor method is invoked, would like to see the following
message:

In the constructor of the ExistentialCrisis class

and I would like to be able to do it without substituting the literal
string 'ExistentialCrisis' for <whatever>.

My question is this: what can be substituted for <whatever> that will
make the example above work?
 
M

Michael Hoffman

Robin said:
self.__class__.__name__

Unless I misunderstood the question, that won't work. That will
give you the name of the class the object is an instance is of.
I think he wants the name of the class the method was defined in.

Here's a way to do that using metaclasses and Python's magic
double-underscore attribute-mangling feature:

"""
class SelfKnowledge(type):
def __init__(cls, name, bases, dict):
setattr(cls, "_%s__%s" % (name, "class_name"), name)
type.__init__(cls, name, bases, dict)

class Nietzsche(object):
__metaclass__ = SelfKnowledge

def __init__(self, text):
self.spam = text
print "In the constructor of the %s class" % self.__class_name

class Kierkegaard(Nietzsche):
def __init__(self, text):
print "Now in the constructor of %s" % self.__class_name
Nietzsche.__init__(self, text)

Nietzsche("Thus Spake Zarathustra")
print

Kierkegaard("Fear and Trembling")
"""

$ python test1.py
In the constructor of the Nietzsche class

Now in the constructor of Kierkegaard
In the constructor of the Nietzsche class
 
D

Diez B. Roggisch

Unless I misunderstood the question, that won't work. That will
give you the name of the class the object is an instance is of.
I think he wants the name of the class the method was defined in.

Where is the difference? The method is defined in a class - and an instance
is created from that class.

This works as expected:

class ExistentialCrisis:
def __init__(self, text):
self.spam = text
print 'In the constructor of the %s class' % self.__class__.__name__


ExistentialCrisis("egal")
 
J

John Roth

Michael Hoffman said:
Unless I misunderstood the question, that won't work. That will
give you the name of the class the object is an instance is of.
I think he wants the name of the class the method was defined in.

If that's the case, then the inspect module should give
the tools to do it without a great deal of angst. Unfortunately,
it doesn't give you the class that defined the method, just
the class that invoked it.

John Roth
 
M

Michael Hoffman

Diez said:
>[Michael Hoffman]:
Unless I misunderstood the question, that won't work. That will
give you the name of the class the object is an instance is of.
I think he wants the name of the class the method was defined in.

Where is the difference? The method is defined in a class - and an instance
is created from that class.

This works as expected:

class ExistentialCrisis:
def __init__(self, text):
self.spam = text
print 'In the constructor of the %s class' % self.__class__.__name__


ExistentialCrisis("egal")

Yes, but this doesn't work if you have a subclass:

"""
class ExistentialCrisisSubclass(ExistentialCrisis):
def __init__(self, text):
print "New constructor"
ExistentialCrisis.__init__(self, text)

ExistentialCrisisSubclass("whoa")
"""

gives you:

New constructor
In the constructor of the ExistentialCrisisSubclass class

But the second line is *not* in the constructor of
ExistentialCrisisSubclass, it is in the constructor of ExistentialCrisis.

while I read the original post as saying that he wanted
"ExistentialCrisis" there instead. Indeed this example
 
M

Michael Hoffman

John said:
If that's the case, then the inspect module should give
the tools to do it without a great deal of angst. Unfortunately,
it doesn't give you the class that defined the method, just
the class that invoked it.

Are you saying that the inspect module *should* give you the
tools to do it but does not?
 
R

Robin Becker

Michael said:
Unless I misunderstood the question, that won't work. That will
give you the name of the class the object is an instance is of.
I think he wants the name of the class the method was defined in.

Here's a way to do that using metaclasses and Python's magic
double-underscore attribute-mangling feature:

"""
class SelfKnowledge(type):
def __init__(cls, name, bases, dict):
setattr(cls, "_%s__%s" % (name, "class_name"), name)
type.__init__(cls, name, bases, dict)

class Nietzsche(object):
__metaclass__ = SelfKnowledge

def __init__(self, text):
self.spam = text
print "In the constructor of the %s class" % self.__class_name

class Kierkegaard(Nietzsche):
def __init__(self, text):
print "Now in the constructor of %s" % self.__class_name
Nietzsche.__init__(self, text)

Nietzsche("Thus Spake Zarathustra")
print

Kierkegaard("Fear and Trembling")
"""

$ python test1.py
In the constructor of the Nietzsche class

Now in the constructor of Kierkegaard
In the constructor of the Nietzsche class

I guess if you're right something along the lines of
import inspect
class A:
_class_name=inspect.currentframe().f_code.co_name
def __init__(self,text,_defining_class_name=_class_name):
print 'text=',text,'_defining_class_name=',_defining_class_name

class B(A):
pass
b=B('aaa')

==>text= aaa _defining_class_name= A


could work as well, but if we only need the local name why not just
insert directly.
 
M

Michael Hoffman

Robin said:
import inspect
class A:
_class_name=inspect.currentframe().f_code.co_name
def __init__(self,text,_defining_class_name=_class_name):
print 'text=',text,'_defining_class_name=',_defining_class_name

class B(A):
pass
b=B('aaa')

That won't work, if you, say, wanted to print out the name of the
class the constructor was defined in for a whole chain of
constructors. Which is about the only case I can think of where
this would be useful.
could work as well, but if we only need the local name why not just
insert directly.

To be honest, that is what I have done every time I have needed
something like this.

I've only used metaclasses in production code once and I still debate
whether that case is a good idea or not.
 

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

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top