python: enforce that a class method is only called from within another class method?
I have a class with two methods A and B. The class will be subclassed. Is there an elegant way to enforce that B() is only ever called on an object of the class from within the A() method?
Let's constrain it and say that A() is only called in one place but subclasses implement A() and can optionally call B() within that. One way I thought of doing this was to wrap the A() call with set开发者_开发百科ting a global variable that says it's ok to call B(), and B() would check this variable when it's invoked. This doesn't seem elegant though.
Any suggestions?
Actual private methods is an evil. Mark your method as internal by adding a leading underscore. This tells programmers not to use it unless they know what they are doing.
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
精彩评论