Reputation: 100
I am a beginner in Python. I would like to know which is the better way of creating attributes...
In the first method I am explicitly defining the attribute and then having a method return a value to it:
class A:
def __init__(self, number):
self.a = self._meth( number)
def _meth(self, num):
#some executable code here
return 8 ** num
In the second variant the method is being called by itself and is creating the attribute by it self.
class A:
def __init__(self, number):
self._meth(num)
def _meth(self, num)
#some executable code here
self.a = 8 ** num
So my question is which one is the more accepted way of going about this?
this is the code I want to use this for...
class Initializer():
def __init__(self):
self.ParseArguments()
self.InitializeLogger()
# Parse command line arguments and display help text
def ParseArguments(self):
help = textwrap.dedent('''\ Help text here''')
Arguments = argparse.ArgumentParser('This Script Pulls NAV data from the '
'AMFI website',
formatter_class=argparse.RawDescriptionHelpFormatter,
description=help)
Arguments.add_argument('-f', '--file',
help= 'location of the config')
self.ArgumentDict = vars(Arguments.parse_args())
self.ArgumentParser = Arguments
def CreateLogFile(self, level, name,):
path = self.ArgumentDict['loc']
if path == None:
if platform.system() == 'Windows':
location = os.environ.get("TEMP") + '\\' + name
elif platform.system == 'Linux':
location = os.getenv("HOME") + '/' + name
else:
print "Unsupported OS"
raise ValueError
else:
location = path
formatter = logging.Formatter("%(asctime)s - %(name)s - "
"%(levelname)s - %(message)s")
logfile = logging.FileHandler(location)
logfile.setLevel(logging.DEBUG)
logfile.setFormatter(formatter)
self.logger.addHandler(logfile)
def InitializeLogger(self):
self.logger = logging.getLogger('main')
if self.ArgumentDict['debug'] == True:
self.logger.setLevel(logging.DEBUG)
else:
self.logger.setLevel(logging.INFO)
self.CreateLogFile(logging.INFO, 'NavUpdaterLog.log'))
Upvotes: 2
Views: 255
Reputation: 288230
Note that you're creating object attributes, not class attributes (Those go directly in the class body). If meth
is only called on initialization, I'd prefer:
class A(object):
def __init__():
# Some executable code here
self.a = 8
Otherwise, if your class can't handle meth
being called every now and then, you should make it a private method by prefixing it with _
or __
.
By the way return None
(with a capitalized None) at the end of a method is unnecessary, that's the default final instruction anyway.
Looking at the updated code, I can't find any need to use classes in the first place. You may want to have a helper method initLogger
, but that's it. Try to:
Upvotes: 3
Reputation:
using init is an understandable way (for other programmer) of creating attribute.
Usually __ init __ is thy way I start my reading of the python class and scan through the methods.
Upvotes: 0
Reputation: 20428
I think the answer is that it depends. If there is only one attribute, like in your example, then the whole body of meth
can go into the __init__
method. If you have say 5-10 attributes to initialize, __init__
would get to long and I would definitely try to refactor the initialization code into functions. If the initialization of each attribute is independent of the other, I would first try to use functions.
def get_attr_a():
# some code
return a
def get_attr_b():
...
return b
...
class A:
def __init__():
self.a = get_attr_a()
self.b = get_attr_b()
...
If the initialization of attributes are dependent on each other, so that b can not be initialized before a is done, then it is a trickier case. That could warrant some kind of factory pattern where the initialization of the object is detached from the class:
class A:
def__init__(self, a, b, c):
self.a, self.b, self.c = a, b, c
def get_attr_a():
return a
def get_attr_b(a):
return b
def create_an_a_class():
a = get_attr_a()
b = get_attr_b(a)
c = get_attr_c(a, b)
....
return A(a, b, c)
Upvotes: 0
Reputation: 4456
I think the correct python way would be to do it the easiest way, removing all unnecessary code.
class A():
def __init__(self):
self.a = 8
If you need to define custom getter and setters, you can use python properties. This in an extract from python documentation :
class C(object):
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
Upvotes: 0
Reputation: 43299
In your second definition, you can only use the method to set the instance variable a
. In your first, you can use the method again if you need it. Also, I don't like looking all over the place for instance variables, so I would go with number one.
Upvotes: 0