I split up my class constructor by letting it call multiple functions, like this:
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
While my interpreter happily runs my code, Pylint has a complaint:
Instance attribute attribute_name defined outside __init__
A cursory Google search is currently fruitless. Keeping all constructor logic in __init__
seems unorganized, and turning off the Pylint warning also seems hack-ish.
What is a/the Pythonic way to resolve this problem?
The idea behind this message is for the sake of readability. We expect to find all the attributes an instance may have by reading its __init__
method.
You may still want to split initialization into other methods though. In such case, you can simply assign attributes to None
(with a bit of documentation) in the __init__
then call the sub-initialization methods.
Just return a tuple from parse_arguments()
and unpack into attributes inside __init__
as needed.
Also, I would recommend that you use Exceptions in lieu of using exit(1)
. You get tracebacks, your code is reusable, etc.
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]
For each attribute you want to set via function, call the function from the init. For example, the following works for me to set the attribute 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