Although I don't recommend the practice, here's a way it could be done using sys._getframe()
:
import sys
class Base(object):
def A(self):
print ' in method A() of a {} instance'.format(self.__class__.__name__)
def B(self):
print ' in method B() of a {} instance'.format(self.__class__.__name__)
if sys._getframe(1).f_code.co_name != 'A':
print ' caller is not A(), aborting'
return
print ' called from A(), continuing execution...'
class Derived(Base):
def A(self):
print " in method A() of a {} instance".format(self.__class__.__name__)
print ' calling self.B() from A()'
self.B()
print '== running tests =='
base = Base()
print 'calling base.A()'
base.A()
print 'calling base.B()'
base.B()
derived = Derived()
print 'calling derived.A()'
derived.A()
print 'calling derived.B()'
derived.B()
The output:
== running tests ==
calling base.A()
in method A() of a Base instance
calling base.B()
in method B() of a Base instance
caller is not A(), aborting
calling derived.A()
in method A() of a Derived instance
calling self.B() from A()
in method B() of a Derived instance
called from A(), continuing execution...
calling derived.B()
in method B() of a Derived instance
caller is not A(), aborting