在__init__中设置用户类的默认/空属性
问题描述
我有不错的编程水平,并从这里的社区中获得了很多价值。然而,我从来没有在编程方面有过太多的学术指导,也没有在真正有经验的程序员旁边工作过。因此,我有时会纠结于‘最佳实践’。
我找不到更好的地方来回答这个问题,尽管可能会有讨厌这类问题的煽动者,但我还是把它贴了出来。如果这让你心烦了,我很抱歉。我只是想学,不是惹你生气。
问题:
当我创建新类时,我是否应该在__init__
中设置所有实例属性,即使它们是None
并且实际上后来在类方法中赋值?
MyClass
的results
属性见下例:
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,我已经在上面的问题上搜索了几次,都没有找到任何人涉及到这个问题。
谢谢
安迪
解决方案
经过大量的研究和与有经验的程序员的讨论,请看下面我认为是这个问题最具毕达式的解决方案。我首先添加了更新的代码,然后添加了说明:
class MyClass:
def __init__(self,df):
self.df = df
self._results = None
@property
def results(self):
if self._results is None:
raise Exception('df_client is None')
return self._results
def generate_results(self, df_results):
#Imagine some calculations here or something
self._results = df_results
描述我了解、更改的内容及其原因:
所有类属性都应包含在
__init__
(初始化器)方法中。这是为了确保可读性和辅助调试。第一个问题是您不能在Python中创建私有属性。所有内容都是公共的,因此可以访问任何部分初始化的属性(例如将结果设置为None)。表示私有属性的惯例是在前面放置一个前导下划线,因此在本例中,我将其更改为
请记住,这只是一种约定,仍然可以直接访问。但是,这是一种处理伪私有属性的高深学派方法。self.results
到self._results
。第二个问题是部分初始化的属性设置为None。由于它被设置为
None
,正如@jferard下面解释的那样,我们现在已经丢失了快速失败提示,并添加了一层用于调试代码的混淆。为了解决这个问题,我们添加了一个getter方法。这可以在上面视为具有上述
这是一个在调用时检查@property
修饰符的函数results()
。self._results
是否为None
的函数。如果是,它将引发异常(故障安全提示),否则将返回对象。@property
修饰符将调用样式从函数更改为属性,因此用户在MyClass实例上使用的所有内容都是.results
,就像任何其他属性一样。(我将设置结果的方法的名称更改为
generate_results()
以避免混淆,并为getter方法释放.results
)如果类中有其他方法需要使用
self._results
,但只有在正确分配的情况下才需要使用,则可以使用self.results
,这样就可以如上所述地烘焙故障安全提示。
我还建议阅读@jferard对这个问题的回答。他深入探讨了这些问题和一些解决方案。我添加我的答案的原因是,我认为在许多情况下,以上就是您所需要的全部(以及毕多德式的方法)。
相关文章