【发布时间】:2017-01-09 17:30:49
【问题描述】:
这与我拥有的其他question 有关,没有答案... 我试图了解 Python binding 到 libclang 的幕后发生了什么,并且真的很难做到。
我已经阅读了大量关于 Python 中的 decorators 和 descriptors 的文章,以了解 CachedProperty class in clang/cindex.py 的工作原理,但仍然无法将所有部分放在一起。
我见过的最相关的文字是one SO answer,而这个code recipe in ActiveState。这对我有点帮助,但是 - 正如我所提到的 - 我仍然不在那里。
那么,让我们切入正题:
我想了解为什么我在创建 CIndex 时会收到 AssertionError。我将只在这里发布相关代码(cindex.py 是 3646 行长..),我希望我不会错过任何与我相关的内容。
我的代码只有一个相关行,即:
index = clang.cindex.Index.create()
这指的是line 2291 in cindex.py,它产生:
return Index(conf.lib.clang_createIndex(excludeDecls, 0))
从现在开始,有一系列的函数调用,我无法解释为什么以及它们是从哪里来的。我将列出代码和pdb 输出以及与每个部分相关的问题:
(需要注意的重要一点:conf.lib 是这样定义的:)
class Config:
...snip..
@CachedProperty
def lib(self):
lib = self.get_cindex_library()
...
return lib
CachedProperty 代码:
class CachedProperty(object):
"""Decorator that lazy-loads the value of a property.
The first time the property is accessed, the original property function is
executed. The value it returns is set as the new value of that instance's
property, replacing the original method.
"""
def __init__(self, wrapped):
self.wrapped = wrapped
try:
self.__doc__ = wrapped.__doc__
except:
pass
def __get__(self, instance, instance_type=None):
if instance is None:
return self
value = self.wrapped(instance)
setattr(instance, self.wrapped.__name__, value)
return value
Pdb 输出:
-> return Index(conf.lib.clang_createIndex(excludeDecls, 0))
(Pdb) s
--Call--
> d:\project\clang\cindex.py(137)__get__()
-> def __get__(self, instance, instance_type=None):
(Pdb) p self
<clang.cindex.CachedProperty object at 0x00000000027982E8>
(Pdb) p self.wrapped
<function Config.lib at 0x0000000002793598>
- 为什么之后的下一个呼叫
Index(conf.lib.clang_createIndex(excludeDecls, 0))是CachedProperty.__get__方法?__init__呢? - 如果
__init__方法没有被调用,那self.wrapped怎么来的 价值?
Pdb 输出:
(Pdb) r
--Return--
> d:\project\clang\cindex.py(144)__get__()-><CDLL 'libcla... at 0x27a1cc0>
-> return value
(Pdb) n
--Call--
> c:\program files\python35\lib\ctypes\__init__.py(357)__getattr__()
-> def __getattr__(self, name):
(Pdb) r
--Return--
> c:\program files\python35\lib\ctypes\__init__.py(362)__getattr__()-><_FuncPtr obj...000000296B458>
-> return func
(Pdb)
-
CachedProperty.__get__应该将值返回到哪里?CDLL.__getattr__方法的调用来自哪里?
对我来说最关键的部分
(Pdb) n
--Call--
> d:\project\clang\cindex.py(1970)__init__()
-> def __init__(self, obj):
(Pdb) p obj
40998256
这是creation of ClangObject,Index 类继承自。
- 但是 - 哪里有对
__init__的一个参数的调用?这是conf.lib.clang_createIndex(excludeDecls, 0)返回的那个吗? - 这个号码 (40998256) 来自哪里?我一遍又一遍地得到相同的数字。据我了解,它应该只是一个数字,而是一个
clang.cindex.LP_c_void_p object,这就是断言失败的原因。
总而言之,对我来说最好的将是这里的函数调用的逐步指导,因为我在这一切中感到有些失落......
【问题讨论】:
标签: python clang decorator python-decorators python-descriptors