【发布时间】:2026-01-19 02:35:02
【问题描述】:
我相信能够包装函数调用是一种常见的做法(至少对我来说是这样)。
例如,一个极简包装函数如下所示:
def wrap(fn, *args, **kwargs):
return fn(*args, **kwargs)
你可以通过
调用任意方法wrap(qt_method, 1, 2, foo='bar')
相当于直接调用
qt_method(1,2, foo='bar')
这通常对我有用。但是,我遇到了一个没有的情况。
QWebView.load() 似乎不喜欢将空字典扩展到其调用签名中。例如。 wrap(my_webview.load, QUrl('http://istonyabbottstillprimeminister.com')) 失败,但有以下例外:
TypeError: QWebView.load(QUrl): argument 1 has unexpected type 'QUrl'.
下面是一个简单的工作示例,它展示了一些可行和不可行的东西。我还没有找到另一种无法像这样包装的 Qt 方法。
import sys
from PyQt4 import QtCore
from PyQt4 import QtGui
from PyQt4.QtWebKit import QWebView
qapplication = QtGui.QApplication(sys.argv)
webview = QWebView()
url = QtCore.QUrl('http://istonyabbottstillprimeminister.com')
# basic wrapping function
def wraps(fn, *args, **kwargs):
return fn(*args, **kwargs)
args = ()
kwargs = {}
wraps(webview.load, url) # Doesn't work
webview.load(url, **kwargs) # Doesn't work
webview.load(url) # works
webview.url(*args, **kwargs) # works
webview.show()
qapplication.exec_()
当您继承 QWebView 并像这样覆盖 load 方法时,此问题也适用:
def load(self *args, **kwargs):
return QWebView.load(self, *args, **kwargs)
当然,如果您改为调用 QWebView.load(self, *args) 或不在方法签名中使用 *args, **kwargs,那么您不会得到异常(这遵循上述最小化工作示例中所见)
任何对此的见解将不胜感激。
【问题讨论】:
-
我认为您应该编辑您的问题以关注核心问题。
webview.load(url, **{})不起作用的事实表明这与“包装”没有任何关系。只是QWebView.load不适用于关键字参数。 -
我只是部分同意你的观点。在直接调用函数时,没有人愿意将 empty 字典解压缩到关键字参数中。发生这种情况的唯一合法情况是当您创建通用函数包装器或在子类化时覆盖方法时。因此,我觉得任何从用例中删除问题的尝试都会导致人们只是告诉我永远不要将
webview.load称为webview.load(url, **{})
标签: python pyqt pyqt4 python-sip