【问题标题】:PyUnicode_FromFormat with (not-unicode) strings带有(非 unicode)字符串的 PyUnicode_FromFormat
【发布时间】:2017-08-02 01:17:18
【问题描述】:

我尝试为一个类创建一个表示函数,我希望它与 python-2.x 和 python-3.x 兼容。但是我注意到,当以%U 传递给PyUnicode_FromFormat 时,普通字符串会出现段错误。我发现的唯一可行的解​​决方法是自己使用PyUnicode_FromObject 将其转换为unicode 对象,然后将结果传递给PyUnicode_FromFormat

/* key and value are arguments for the function. */
PyObject *repr;
if (PyUnicode_CheckExact(key)) {
    repr = PyUnicode_FromFormat("%U=%R", key, value);
} 
else {
    PyObject *tmp = PyUnicode_FromObject(key);
    if (tmp == NULL) {
        return NULL;
    }
    repr = PyUnicode_FromFormat("%U=%R", tmp, value);
    Py_DECREF(tmp);
}

关键是我希望表示没有""(或''),如果我使用%R%S 会添加。

我最近才发现这个问题,我到处都在使用PyUnicode_FromFormat("%U", something);,所以我的问题是:这可以在保持 Python 2.x 和 3.x 兼容的同时简化吗?

【问题讨论】:

  • 我对此没有很好的答案(而且我认为不存在),但我很想简化它以删除 if 语句并遵循 else 路径每次。对已经是 unicode 对象的东西调用 PyUnicode_FromObject 只会执行 incref 并立即返回该对象,因此始终这样做不会花费太多。
  • @DavidW 并不像我想的那么简单,但它确实让它更短更简单。您介意将其添加为答案吗?我不会马上接受它(仍然希望有更简单的方法),但它确实很有帮助。
  • 这段代码有问题吗?如果不是(即它按预期工作),这个问题可能属于 Code Review,而不是 Stack Overflow。
  • @QPaysTaxes CodeReview 想要“真实有效的代码”而不是人工代码。我实际上是在询问这个 code-sn-p 并且我不想对代码进行全面审查;所以这将是off-topic on code-review
  • (1) 此代码是真实的,因为它是实际使用的代码,不是伪代码或截断代码。您打算用它替换其他代码是无关紧要的。 (2) 我看不出它是怎么坏的;如果有问题,请强调。 (另外,我在那里有 4k 代表;我想我现在知道什么是主题 :))

标签: python c python-2.7 python-c-api


【解决方案1】:

我认为不存在一种非常简单的方式来做你想做的事。我能看到的最好的方法是仅使用您的 else 案例来消除 if 语句,因此始终调用 PyUnicode_FromObject

PyObject *tmp = PyUnicode_FromObject(key);
if (tmp == NULL) {
    return NULL;
}
repr = PyUnicode_FromFormat("%U=%R", tmp, value);
Py_DECREF(tmp);

如果您查看the implementation of PyUnicode_FromObject,您会看到它所做的第一件事是PyUnicode_CheckExact,在这种情况下,它会返回原始对象的increfed 版本。因此,完成的额外工作非常少(对于 key 已经是 unicode 的情况)并且对于 key 不是 unicode 的情况应该稍微更有效,因为您避免了分支。

【讨论】:

    猜你喜欢
    • 2015-10-16
    • 1970-01-01
    • 1970-01-01
    • 2016-09-30
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多