开发者

python: enforce that a class method is only called from within another class method?

开发者 https://www.devze.com 2023-02-06 15:36 出处:网络
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?

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
0

精彩评论

暂无评论...
验证码 换一张
取 消