pygtk3 可以反射吗?

8 投票
3 回答
989 浏览
提问于 2025-04-17 04:48

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 个回答

0

你可以使用其他一些内置的函数,比如 dir()、vars() 等等。

http://docs.python.org/library/functions.html

还有一个很有用的工具叫 pydoc:

pydoc gi.repository.Gtk
0

我认为这就是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模块,也在寻找“修复”这个(...)的方法,解决办法就是把它放在文档字符串里,但我觉得这样容易出错,因为每次我修改函数时都得更新文档字符串。

4

现在,我觉得这个还没有准备好。不过,你还是可以手动查看一下 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>

所以所有的信息其实都已经在里面了。

撰写回答