PEP8和PyQt,如何协调函数的大写形式?

37

我开始在一些项目中使用PyQt,但我遇到了一个风格上的困境。PyQt的函数使用驼峰式命名,但我更喜欢遵循PEP8使用下划线和全小写字母来命名函数。

因此,一方面,我可以继续遵循PEP8,这意味着我的代码将混合使用驼峰式和下划线式函数调用,即使是我的类也会有混合的函数名称,因为我需要重载函数如mousePressEvent。或者,我可以打破PEP8,为了一致性而采用驼峰式命名所有函数名称。

我意识到这是主观的,只是我个人喜好的问题,但我想听听别人做什么以及为什么选择这样做。


1
我刚开始学习PyQt。函数是唯一的问题吗?还是PyQt变量也经常被访问?我考虑在我的PyQt UI代码中使用camelCase作为函数名称,但仍遵循PEP8约定的变量名称。尽管如此,我担心这可能会在后面创建混乱的组合。 - Michael Scheper
1
无论如何,我并不完全同意这是主观的。我欣赏 PyQt,但我认为他们没有遵循 PEP8 是一种伤害。(再说了,即使库的名称也不是非常 Pythonic。QtPy 将会更好,因为我在两个大陆遇到的所有讲英语的开发人员都会把它发音成“cutie-pie”。;-) ) - Michael Scheper
6个回答

34

如果我是你,我不会和你的框架争论,就像一般原则一样,我不会和城市议会争论;-)。 我碰巧与PEP 8规定的小写带下划线函数名称偏好相同,但当我在强制使用不同大写格式的框架中编程时,我也接受采用该样式,因为我无法说服框架采用“更好”的样式,而样式不一致性(混合不同样式)真的更糟。

当然,如果您正在使用多个框架,某些混合是不可避免的...例如,PyQt具有驼峰样式,标准Python库功能具有小写和下划线!-)。 但是,由于像Qt这样的框架通常旨在通过子类化进行扩展,而标准Python库的设计方面较少,所以在大多数情况下,当强制使用大写字母风格时(因为您需要覆盖方法,所以无法选择不同的大写字母),它将被强制为驼峰样式(由Qt),只有很少是小写(由标准Python库)。 因此,在这种情况下采用Qt样式仍然是较小的恶。


15

《PEP8文档》中指出这种情况下应该怎么做(重点是我的):

新的模块和包(包括第三方框架)应该按照这些标准编写,但如果现有库采用不同的样式,则内部一致性更受青睐。


7
在2020年12月,随着Qt 6.0的发布,Qt for Python 6 / PySide6(Qt的官方Python绑定)也发布了,引入了一个名为__feature__的新选项。通过此选项,您可以拥有PEP8兼容的蛇形命名法方法和真正的属性的Qt对象。

旧风格:

table = QTableWidget()
table.setColumnCount(2)

button = QPushButton("Add")
button.setEnabled(False)

layout = QVBoxLayout()
layout.addWidget(table)
layout.addWidget(button)

新的 PySide6 样式:
from __feature__ import snake_case, true_property

table = QTableWidget()
table.column_count = 2

button = QPushButton("Add")
button.enabled = False

layout = QVBoxLayout()
layout.add_widget(table)
layout.add_widget(button)

6

使用最合适的方式。

如果您正在子类化Qt类,或者有一个与它们密切集成的函数,请使用UseCamelCase

否则,use_underscores


10
这清晰地向代码读者展示了与Qt相关的部分以及与之无关的部分。 - Eric O. Lebigot
在一个好的应用程序中,实际上只有很少量的代码会使用GUI工具包。 - phkahler

1

如果你子类化此类,可以使用下划线。并且你可以用下划线命名你的方法,PyQt4 将能够使用它们,就像你用驼峰命名一样。

class SomeClass(object):
    def __getattr__(self, attr):
        if '_' in attr:
            new = [c for c in attr]
            while True:
                try:
                    new_char = new[new.index('_') + 1].upper()
                    new[new.index('_'):new.index('_') + 2] = new_char
                except (IndexError, ValueError):
                    break
        else:
            for c in attr:
                if c.isupper():
                    new = []
                    for i, c in enumerate(attr):
                        if i != 0 and c.isupper():
                            new.append('_')
                        new.append(c.lower())
                    break
        try:
            return super(type(self), self).__getattribute__(''.join(new))
        except Exception:
            return super(type(self), self).__getattribute__(attr)

0
也许明智的做法是使用模块来分离不同模块中的样式。至少尝试将基本的PEP8样式代码模块化为自己的辅助函数模块。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接