Python 可以确定访问方法的对象的类吗

发布于 2024-08-06 09:25:40 字数 844 浏览 2 评论 0原文

无论如何,有没有做这样的事情:

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"

Where caller in 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

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

Is there anyway to do something like this:

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"

Where caller in A uses some form of introspection to determine the class of the calling method's object?

EDIT:

In the end, I put this together based on some of the suggestions:

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

It's not perfect for all the reasons supplied, but thanks for the responses: they were a big help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

念三年u 2024-08-13 09:25:40

假设调用者是一个方法,那么是的,您可以通过查看前一帧并从局部变量中选出 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"

哎呀,但它确实有效。现在为什么你想要这样做完全是另一个问题,我怀疑有更好的方法。 A 不允许调用 B 的整个概念很可能是一个错误。

Assuming the caller is a method, then yes you can, by looking in the previous frame, and picking out self from the locals.

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ŷ as heck, but it works. Now why you would want to do this is another question altogether, I suspect that there is a better way. The whole concept of A isn't allowed to call B is likely to be a mistake.

星星的轨迹 2024-08-13 09:25:40

调用者始终是 A 的实例。您在 B 方法内调用它的事实不会改变这一点。换句话说:在B.foo中,refA的实例,因此调用ref.foo() 是对 A 的调用,B 不参与该调用(它可能发生在顶层)。

唯一明智的方法是传递对 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"

The caller is always an instance of A. The fact that you're calling it inside a B method doesn't change that. In other words: Insiode B.foo, ref is an instance of A, so calling ref.foo() is a call on A, B is not involved on that call (it could happen top-level).

The only sane way is to pass a reference to self so A can check if it is B or not.

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"
作死小能手 2024-08-13 09:25:40

像这样的东西可能会更好地满足您的需求:

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

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

class C(A):
    pass

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

Something like this may meet your needs better:

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

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

class C(A):
    pass

...but it's difficult to say without knowing exactly what you're trying to do.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文