198

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

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 警告也似乎是 hack-ish。

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

4

6 回答 6

210

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

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

于 2013-10-10T09:57:25.477 回答
36

只需根据需要返回一个元组parse_arguments()并解压到里面的属性__init__中。

另外,我建议您使用 Exceptions 代替使用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]
于 2013-10-10T00:21:51.660 回答
4

解决这个问题的最佳实践是你需要先在 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')
于 2020-09-24T16:43:59.673 回答
2

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

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

于 2019-09-11T09:34:48.413 回答
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
于 2018-12-30T19:07:33.147 回答
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

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

如果您不关心类型并且不想object()使用 use 创建新对象:

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

那样None会导致类型不匹配错误。

于 2019-12-20T10:14:46.990 回答