在__init__外定义的实例属性attribute_name

时间:2013-10-10 00:04:51

标签: python constructor pylint

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

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警告似乎也很糟糕。

什么是 Pythonic 解决此问题的方法?

6 个答案:

答案 0 :(得分:122)

此消息背后的想法是为了便于阅读。我们期望通过阅读其__init__方法找到实例可能具有的所有属性。

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

答案 1 :(得分:26)

只需从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]

答案 2 :(得分:1)

尽管一般不建议在 init 之外定义实例变量,但在少数情况下自然是这样。例如,当您有一个父类定义了几个子类将不使用的变量时,这些变量的定义将浪费其子类的时间或资源,或者仅仅是不美观。

对此的一种可能的解决方案是使用init-extension函数,每个子类都可以重写该函数,并在该函数中使用setattr函数以定义类唯一的实例变量。也许这也不是太美观,但它消除了此处讨论的掉毛警告。

答案 3 :(得分:0)

对于要通过函数设置的每个属性,请从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

答案 4 :(得分:0)

如果您使用的是Python 3,则可以尝试

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将导致类型不匹配错误。

答案 5 :(得分:0)

解决此问题的最佳实践是您需要首先在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')