pygtk3 可以反射吗?
Python的一个很棒的功能就是可以查看方法和函数的内部信息。举个例子,如果你想知道math.log
这个函数的参数是什么,可以在ipython中运行以下代码:
In [1]: math.log?
Type: builtin_function_or_method
Base Class: <type 'builtin_function_or_method'>
String Form: <built-in function log>
Namespace: Interactive
Docstring:
log(x[, base])
Return the logarithm of x to the given base.
If the base not specified, returns the natural logarithm (base e) of x.
这样你就能看到x
和可选的base
是这个函数的参数。
在新的gtk3和自动生成的pygobject绑定中,我在尝试的所有例子里,只能看到每个gtk方法的参数都是(*args, **kwargs)
。
比如:Label.set_text 这个方法需要一个字符串:
In [1]: from gi.repository import Gtk
In [2]: mylabel = Gtk.Label("hello")
In [3]: mylabel.set_text?
Type: instancemethod
Base Class: <type 'instancemethod'>
String Form: <bound method Label.set_text of <Label object at 0x275b230 (GtkLabel at 0x28cd040)>>
Namespace: Interactive
File: /usr/lib/python2.7/dist-packages/gi/types.py
Definition: L.set_text(*args, **kwargs)
Docstring:
<no docstring>
现在的问题是:这种(对于python绑定失去方法内部信息的情况)是否会随着对pygobjects的文档投入更多精力而改变,还是说这是由于pygobjects的工作方式而注定要一直存在的?
3 个回答
你可以使用其他一些内置的函数,比如 dir()、vars() 等等。
http://docs.python.org/library/functions.html
还有一个很有用的工具叫 pydoc:
pydoc gi.repository.Gtk
我认为这就是C语言接口创建Python模块的方式。例如:
>>> import inspect
>>> inspect.getargspec(math.log)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\inspect.py", line 813, in getargspec
raise TypeError('{!r} is not a Python function'.format(func))
TypeError: <built-in function log> is not a Python function
我知道的唯一查看内置函数方法参数的方法就是查看文档字符串。
>>> help(math.log)
Help on built-in function log in module math:
log(...)
log(x[, base])
Return the logarithm of x to the given base.
If the base not specified, returns the natural logarithm (base e) of x.
我自己写过C语言的Python模块,也在寻找“修复”这个(...)的方法,解决办法就是把它放在文档字符串里,但我觉得这样容易出错,因为每次我修改函数时都得更新文档字符串。
现在,我觉得这个还没有准备好。不过,你还是可以手动查看一下 Gtk-3.0.gir
文件(在我的系统中,这个文件位于 /usr/share/gir-1.0/Gtk-3.0.gir
)。
这个 gir 文件其实就是一个 xml 文件,主要用来探索你所使用的编程语言所暴露的接口。举个例子,你可以通过查找 <class name="Label"
来找到 Label
类。在 class
标签里面,有一个 doc
标签,里面有关于这个小部件应该做什么的详细信息。此外,还有很多 method
标签,其中一个就是你在例子中感兴趣的: <method name="set_text"
。在这个 method
标签里,不仅有一个 doc
标签来描述这个方法,还有一个 parameters
标签,里面包含了一些 parameter
标签,用来描述每个参数的名称、说明和类型:
<parameters>
<parameter name="str" transfer-ownership="none">
<doc xml:whitespace="preserve">The text you want to set</doc>
<type name="utf8" c:type="gchar*"/>
</parameter>
</parameters>
所以所有的信息其实都已经在里面了。