【问题标题】:How to access a caller method's __class__ attribute from a callee function in Python?如何从 Python 中的被调用者函数访问调用者方法的 __class__ 属性?
【发布时间】:2019-10-18 10:13:42
【问题描述】:

这里的__class__ 不应与self.__class__ 混淆,我已经可以使用inspect 模块访问:

import inspect


class A:

    def __init__(self):
        print(__class__.__name__)  # I want to move this statement inside f
        f()


class B(A):
    pass


def f():
    prev_frame = inspect.currentframe().f_back
    self = prev_frame.f_locals["self"]
    print(self.__class__.__name__)


B()  # prints A B

【问题讨论】:

    标签: python code-inspection class-attributes


    【解决方案1】:

    implicit __class__ reference 仅当您在方法中实际引用它(或使用super)时才会在编译时创建。例如这段代码:

    class Foo:
        def bar(self):
            print('bar', locals())
    
        def baz(self):
            print('baz', locals())
    
            if False:
                __class__
    
    if __name__ == '__main__':
        foo = Foo()
    
        foo.bar()
        foo.baz()
    

    产生这个输出:

    bar {'self': <__main__.Foo object at 0x10f45f978>}
    baz {'self': <__main__.Foo object at 0x10f45f978>, '__class__': <class '__main__.Foo'>}
    

    要找到调用函数的类(在大多数情况下),您可以将一些 CPython 特定的 inspect 咒语链接在一起:

    1. 找到调用函数:How to get current function into a variable?
    2. 查找该函数的类:Get defining class of unbound method object in Python 3

    我不会推荐它。

    【讨论】:

    • 由于 OP 只需要类名,他们可以使用inspect 来获取调用函数并从该函数的__qualname__ 中提取类名。不需要获取类对象。
    • @Aran-Fey:问题标题使用__class__ 引用,所以我假设__class__.__name__ 只是一个例子。但是,是的,如果您只需要父类的名称,那么您可以使用第一个链接问题和__qualname__ 中的方法。
    • 我实际上是在尝试在 Python 中重新实现 super 类以了解其行为,因此我需要类对象 @Aran-Fey。我在语法糖部分super() == super(__class__, self)。为什么他们选择只创建__class__ 隐式闭包引用“如果类主体中的任何方法引用__class__super”而不是总是?我的super 类重新实现没有被称为super,所以__class__ 没有被创建,我只剩下@Blender CPython hack(顺便谢谢你)。
    • @Maggyero:我对 CPython 内部结构或它的历史不是很熟悉,所以我不能 100% 确定。自从第一次提交引入它以来就是这样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多