实例属性 attribute_name 在 __init__ 外部定义

问题描述 投票:0回答:6

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

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方法是什么?

python constructor pylint
6个回答
239
投票

此消息背后的想法是为了可读性。我们期望通过读取实例的

__init__
方法来找到实例可能具有的所有属性。

您可能仍然想将初始化拆分为其他方法。在这种情况下,您可以简单地将属性分配给

None
中的
__init__
(带有一些文档),然后调用子初始化方法。


41
投票

只需从

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]

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')

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

0
投票

虽然一般情况下不建议在

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

对此的一种可能的解决方案是使用每个子类都可以重写的 init 扩展函数,并在该函数中使用函数

setattr
来定义类唯一的实例变量。也许这也不太美观,但它消除了这里讨论的掉毛警告。


-2
投票

如果你使用的是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()
创建新对象,请使用:

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

因为

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

© www.soinside.com 2019 - 2024. All rights reserved.