我通过让它调用多个函数来拆分我的类构造函数,如下所示:
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 解决此问题的方法?
答案 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')