我的编程水平不错,并从这里的社区中获得了很多价值。然而,我从来没有接受过太多编程方面的学术教学,也没有在真正有经验的程序员旁边工作过。因此,我有时会与“最佳实践”作斗争。
问题:
当我创建一个新类时,我是否应该在 __init__
中设置所有实例属性,即使它们是 None
并且实际上稍后在类方法中赋值?
请参阅下面的示例,了解 --- 的属性 results
MyClass
:
class MyClass:
def __init__(self,df):
self.df = df
self.results = None
def results(df_results):
#Imagine some calculations here or something
self.results = df_results
我在其他项目中发现,当类属性仅出现在类方法中时,类属性可能会被掩埋,并且有很多事情要做。
那么对于经验丰富的专业程序员来说,标准做法是什么?为了便于阅读,您会在 __init__
中定义所有实例属性吗?
如果有人有关于我在哪里可以找到这些原则的材料的任何链接,那么请把它们放在一个答案中,我们将不胜感激。我知道 PEP-8 并且已经在上面多次搜索了我的问题,但找不到任何人涉及这个。
谢谢
安迪
原文由 Andy 发布,翻译遵循 CC BY-SA 4.0 许可协议
在与经验丰富的程序员进行大量研究和讨论之后,请在下面查看我认为对这个问题最 Pythonic 的解决方案。我首先包括了更新的代码,然后是叙述:
描述我所学到的、改变的以及原因:
所有类属性都应包含在
__init__
(初始化程序)方法中。这是为了确保可读性和帮助调试。第一个问题是您不能在 Python 中创建私有属性。一切都是公开的,因此可以访问任何部分初始化的属性(例如设置为 None 的结果)。指示私有属性的约定是在前面放置一个前导下划线,因此在这种情况下,我将其更改为
self.results
到self._results
。请记住,这只是惯例,仍然可以直接访问
self._results
。然而,这是处理伪私有属性的 Pythonic 方式。None
,正如下面的@jferard 解释的那样,我们现在已经失去了快速失败提示并添加了一层混淆来调试代码。为了解决这个问题,我们添加了一个 getter 方法。这可以看作上面的函数
results()
上面有@property
装饰器。这是一个在调用时检查
self._results
是否为None
的函数。如果是这样,它将引发异常(故障安全提示),否则它将返回该对象。@property
装饰器将调用样式从函数更改为属性,因此用户必须在 MyClass 的实例上使用.results
就像任何其他属性一样。self._results
,但只有在正确分配时,您才可以使用self.results
,这样故障安全提示就会被嵌入多于。我还建议阅读@jferard 对这个问题的回答。他深入探讨了问题和一些解决方案。我添加我的答案的原因是,我认为在很多情况下,以上就是你所需要的(以及 Pythonic 的方式)。