实例属性attribute_name定义在__init__之外

我通过让类构造函数调用多个函数来拆分类构造函数,如下所示:

class Wizard:
def __init__(self, argv):
self.parse_arguments(argv)
self.wave_wand() # declaration omitted


def parse_arguments(self, argv):
if self.has_correct_argument_count(argv):
self.name = argv[0]
self.magic_ability = argv[1]
else:
raise InvalidArgumentsException() # declaration omitted


# ... irrelevant functions omitted

当我的解释器愉快地运行我的代码时,Pylint有一个抱怨:

Instance attribute attribute_name defined outside __init__

粗略的谷歌搜索目前没有结果。将所有构造函数逻辑保存在__init__中似乎是杂乱无章的,关闭Pylint警告也似乎是一种拙劣的做法。

解决这个问题的/the 神谕的方法是什么?

134462 次浏览

只需从parse_arguments()返回一个元组,并根据需要将其解压缩到__init__中的属性中。

另外,我建议你使用异常来代替exit(1)。你得到了回溯,你的代码是可重用的,等等。

class Wizard:
def __init__(self, argv):
self.name,self.magic_ability = self.parse_arguments(argv)


def parse_arguments(self, argv):
assert len(argv) == 2
return argv[0],argv[1]

这条消息背后的想法是为了可读性。我们希望通过读取实例的__init__方法来找到实例可能具有的所有属性。

不过,您可能仍然希望将初始化拆分为其他方法。在这种情况下,你可以简单地将属性赋给__init__中的None(带一些文档),然后调用子初始化方法。

对于想要通过function设置的每个属性,从init调用该函数。例如,下面的工作为我设置属性ascii_txt

def __init__(self, raw_file=None, fingerprint=None):
self.raw_file = raw_file
self.ascii_txt = self.convert_resume_to_ascii()


def convert_resume_to_ascii(self):
ret_val = self.raw_file.upper()
return ret_val

虽然通常不建议在初始化之外定义实例变量,但在极少数情况下,这样做是很自然的。例如,当你有一个父类,它定义了几个它的子类不会使用的变量,而这些变量的定义会让它的子类浪费时间或资源,或者仅仅是不美观。

一种可能的解决方案是使用初始化扩展函数,每个子类都可以覆盖该函数,并在该函数中使用函数setattr来定义类唯一的实例变量。也许这也不太美观,但它消除了这里讨论的绒线警告。

如果你正在使用python3,你可以试试

class Wizard:
def __init__(self, argv):
self.name: str = str()
self.magic_ability: str = str()
self.parse_arguments(argv)
self.wave_wand() # declaration omitted


def parse_arguments(self, argv):
if self.has_correct_argument_count(argv):
self.name = argv[0]
self.magic_ability = argv[1]
else:
raise InvalidArgumentsException() # declaration omitted


# ... irrelevant functions omitted

虽然不像公认的答案那样python化,但它应该可以摆脱Pylint警告。

如果你不关心类型,也不想用object()创建一个新对象,使用:

class Wizard:
def __init__(self, argv):
self.name = type(None)()
# ...

因为None将导致类型不匹配错误。

解决这个问题的最佳实践是你需要首先在Init部分中构建参数, 然后在Def

中调整它
class MainApplication(tk.Frame):
def __init__(self, master):
self.master = master
tk.Frame.__init__(self, self.master)
self.settingsFrame = None
self.create_widgets(master)


def create_widgets(self, master):
# frame Container
self.settingsFrame = tk.Frame(self.master, width=500, height=30, bg='white')