这与我遇到的其他问题有关,没有答案......我试图了解Python 绑定到libclang的幕后发生的事情,并且很难做到这一点。
我已经阅读了大量关于Pythondecorators
和descriptors
Python 的文章,以了解clang/cindex.py 中的 CachedProperty 类是如何工作的,但仍然无法将所有部分放在一起。
我见过的最相关的文本是一个 SO answer和 ActiveState 中的这个代码配方。这对我有点帮助,但是——正如我所提到的——我仍然不在那里。
所以,让我们切入正题:我想了解我为什么要AssertionError
创建 CIndex。我将只在这里发布相关代码(cindex.py 是 3646 行长..),我希望我不会错过任何与我相关的内容。我的代码只有一个相关行,即:
index = clang.cindex.Index.create()
这指的是 cindex.py 中的第 2291 行,它产生:
return Index(conf.lib.clang_createIndex(excludeDecls, 0))
从现在开始,有一系列的函数调用,我无法解释为什么它们来自于 WTH。我将列出与pdb
每个部分相关的问题的代码和输出:
(需要注意的重要一点:conf.lib 定义如下:)
class Config:
...snip..
@CachedProperty
def lib(self):
lib = self.get_cindex_library()
...
return lib
缓存属性代码:
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))
是 toCachedProperty.__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
这是Index 继承自的类的创建。ClangObject
- 但是 - 哪里有
__init__
一个参数调用?这是那个conf.lib.clang_createIndex(excludeDecls, 0)
回来的吗? - 这个号码(40998256)来自哪里?我一遍又一遍地得到相同的数字。据我了解,它应该只是一个数字,但这
clang.cindex.LP_c_void_p object
就是断言失败的原因。
总而言之,对我来说最好的方法是逐步指导这里的函数调用,因为我对这一切感到有点迷失......