2

反正有没有做这样的事情:

class A:
    def foo(self):
        if isinstance(caller, B):
           print "B can't call methods in A"
        else:
           print "Foobar"
class B:
    def foo(self, ref): ref.foo()

class C:
    def foo(self, ref): ref.foo()


a = A();
B().foo(a)    # Outputs "B can't call methods in A"
C().foo(a)    # Outputs "Foobar"

调用者在哪里A使用某种形式的自省来确定调用方法对象的类?

编辑

最后,我根据一些建议将其放在一起:

import inspect
...
def check_caller(self, klass):
    frame = inspect.currentframe()
    current = lambda : frame.f_locals.get('self')
    while not current() is None:
        if isinstance(current(), klass): return True
        frame = frame.f_back
    return False

由于提供的所有原因,它并不完美,但感谢您的回复:他们提供了很大的帮助。

4

3 回答 3

6

假设调用者是一种方法,那么可以,通过查看前一帧并self从本地人中挑选出来。

class Reciever:
    def themethod(self):
        frame = sys._getframe(1)
        arguments = frame.f_code.co_argcount
        if arguments == 0:
            print "Not called from a method"
            return
        caller_calls_self = frame.f_code.co_varnames[0]
        thecaller = frame.f_locals[caller_calls_self]
        print "Called from a", thecaller.__class__.__name__, "instance"

Üglŷ 真是太棒了,但它确实有效。现在为什么要这样做完全是另一个问题,我怀疑有更好的方法。不允许 A 调用 B 的整个概念可能是一个错误。

于 2009-09-30T12:20:31.713 回答
4

调用者始终是 A 的一个实例。您在 B 方法中调用它的事实并不会改变这一点。换句话说: Insiode B.foo,ref是 的一个实例A,所以调用ref.foo()是一个调用 on AB不涉及该调用(它可能发生在顶层)。

唯一明智的方法是传递对的引用,self以便 A 可以检查它是否为 B。

class A(object):
    def foo(self, caller=None):
        if isinstance(caller, B):
           print "B can't call methods in A"
        else:
           print "Foobar"

class B(object):
    def foo(self, ref): ref.foo(self)

class C(object):
    def foo(self, ref): ref.foo(self)

a = A();
B().foo(a)    # Outputs "B can't call methods in A"
C().foo(a)    # Outputs "Foobar"
a.foo()       # Outputs "Foobar"
于 2009-09-30T12:02:03.280 回答
0

这样的事情可能会更好地满足您的需求:

class A(object):
    def foo(self):
        # do stuff

class B(A):
    def foo(self):
        raise NotImplementedError

class C(A):
    pass

...但是如果不确切知道您要做什么,就很难说。

于 2009-09-30T13:58:58.887 回答