我通过让它调用多个函数来拆分我的类构造函数,如下所示:
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方法是什么?
此消息背后的想法是为了可读性。我们期望通过读取实例的
__init__
方法来找到实例可能具有的所有属性。
您可能仍然想将初始化拆分为其他方法。在这种情况下,您可以简单地将属性分配给
None
中的 __init__
(带有一些文档),然后调用子初始化方法。
只需从
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部分构建参数, 然后在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')
对于要通过函数设置的每个属性,请从 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
虽然一般情况下不建议在
__init__
之外定义实例变量,但在极少数情况下这是自然的。例如,当您有一个父类定义了几个其子类不会使用的变量时,这些变量的定义将使其子类浪费时间或资源,或者根本不美观。
对此的一种可能的解决方案是使用每个子类都可以重写的 init 扩展函数,并在该函数中使用函数
setattr
来定义类唯一的实例变量。也许这也不太美观,但它消除了这里讨论的掉毛警告。
如果你使用的是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
会导致类型不匹配错误。