Nei*_*l G 7 python metaprogramming python-3.3
给出x = C.f
之后:
class C:
def f(self):
pass
Run Code Online (Sandbox Code Playgroud)
我会打电话给谁x
回来C
?
我能做的最好的是exec
解析部分x.__qualname__
,这是丑陋的:
exec('d = ' + ".".join(x.__qualname__.split('.')[:-1]))
Run Code Online (Sandbox Code Playgroud)
对于一个用例,想象一下我想要一个装饰器来添加super
对它应用的任何方法的调用.那个只给出函数对象的装饰器怎么能把类带到super
(???
下面)?
def ensure_finished(iterator):
try:
next(iterator)
except StopIteration:
return
else:
raise RuntimeError
def derived_generator(method):
def new_method(self, *args, **kwargs):
x = method(self, *args, **kwargs)
y = getattr(super(???, self), method.__name__)\
(*args, **kwargs)
for a, b in zip(x, y):
assert a is None and b is None
yield
ensure_finished(x)
ensure_finished(y)
return new_method
Run Code Online (Sandbox Code Playgroud)
如果您的目的是摆脱该exec
语句,但仍然愿意使用该__qualname__
属性,即使您仍然需要手动解析它,则至少在简单情况下,以下方法似乎可行:
x.__globals__[x.__qualname__.rsplit('.', 1)[0]]
Run Code Online (Sandbox Code Playgroud)
要么:
getattr(inspect.getmodule(x), x.__qualname__.rsplit('.', 1)[0])
Run Code Online (Sandbox Code Playgroud)
我不是Python
专家,但是考虑到以下文档摘录,我认为第二种解决方案更好:
来自:新增功能Python 3.3
:
函数和类对象具有一个新
__qualname__
属性,表示从模块顶层到其定义的“路径”。对于全局函数和类,这与相同__name__
。对于其他函数和类,它提供了有关它们的实际定义位置以及如何从全局范围访问它们的更好信息。
对于嵌套的类,方法和嵌套函数,该
__qualname__
属性包含指向模块顶层对象的点线路径。
编辑:
如@eryksun的评论所指出的那样,这样的解析__qualname__
超出了其预期的用途,并且考虑到如何__qualname__
反映闭包是极其脆弱的。一种更强大的方法需要排除形式的闭包命名空间name.<locals>
。例如:
>>> class C:
... f = (lambda x: lambda s: x)(1)
...
>>> x = C.f
>>> x
<function C.<lambda>.<locals>.<lambda> at 0x7f13b58df730>
>>> x.__qualname__
'C.<lambda>.<locals>.<lambda>'
>>> getattr(inspect.getmodule(x), x.__qualname__.rsplit('.', 1)[0])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'C.<lambda>.<locals>'
Run Code Online (Sandbox Code Playgroud)
可以通过以下方式处理此特定情况:
>>> getattr(inspect.getmodule(x),
... x.__qualname__.split('.<locals>', 1)[0].rsplit('.', 1)[0])
<class '__main__.C'>
Run Code Online (Sandbox Code Playgroud)
尽管如此,目前尚不清楚还有哪些其他极端情况或将来的版本中可能还会出现。
如@MichaelPetch的评论中所述,此答案仅与Python 3.3
向前有关,因为只有在__qualname__
属性被引入语言时才如此。
Python
版本等效的功能。有关也可以处理绑定方法的完整解决方案,请参考此答案。
归档时间: |
|
查看次数: |
817 次 |
最近记录: |