如果你的目的是摆脱exec语句,但愿意使用
the __qualname__ attribute,即使你仍然需要手动解析它,那么至少对于简单的情况,以下似乎可行:
x.__globals__[x.__qualname__.rsplit('.', 1)[0]]
要么:
getattr(inspect.getmodule(x), x.__qualname__.rsplit('.', 1)[0])
我不是Python专家,但我认为第二种解决方案更好,考虑以下文档摘录:
Functions and class objects have a new __qualname__ attribute representing the “path” from the module top-level to their definition. For global functions and classes, this is the same as __name__. For other functions and classes, it provides better information about where they were actually defined, and how they might be accessible from the global scope.
For nested classed, methods, and nested functions, the __qualname__ attribute contains a dotted path leading to the object from the module top-level.
编辑:
>如@eryksun的评论中所述,解析__qualname__就像这样超出了它的预期用途,考虑到__qualname__如何反映closures,它非常脆弱.更强大的方法需要排除表单名称的闭包命名空间.< locals>.例如:
>>> class C:
... f = (lambda x: lambda s: x)(1)
...
>>> x = C.f
>>> x
.. at 0x7f13b58df730>
>>> x.__qualname__
'C...'
>>> getattr(inspect.getmodule(x), x.__qualname__.rsplit('.', 1)[0])
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'module' object has no attribute 'C..'
可以通过以下方式处理此特定情况:
>>> getattr(inspect.getmodule(x),
... x.__qualname__.split('.', 1)[0].rsplit('.', 1)[0])
尽管如此,目前还不清楚现在存在哪些其他角落案例,或者未来版本中可能会出现这种情况.
>正如@MichaelPetch的评论中所指出的,这个答案仅适用于Python 3.3之前的版本,因为只有the __qualname__ attribute was introduced才能使用该语言.
>但是,根据@WouterBolsterlee,github.com/wbolster/qualname提供了旧版Python的等效版本.
>有关处理绑定方法的完整解决方案,请参阅this answer.