Reputation: 771
When defining a class and you need to use an argument twice is it better to keep using the argument or use the self version as soon as it is made?
class Example:
def __init__(self, name):
self.name = name
self.name_upper = name.upper()
or
class Example:
def __init__(self, name):
self.name = name
self.name_upper = self.name.upper()
And what about with list?
class Example:
def __init__(self, name):
self.name = name
self.name_list = [name,name,name]
class Example:
def __init__(self, name):
self.name = name
self.name_list = [self.name,self.name,self.name]
Upvotes: 0
Views: 40
Reputation: 155734
TL;DR: In the specific cases you're describing, it doesn't matter. It's a very small trade-off between speed and safety against future changes, but there's no right answer.
If there is no massaging of the argument before it's stored in the attribute, then it doesn't really matter. Using the unqualified name will be slightly faster (self.name
on CPython involves a cheap LOAD_FAST
and a significantly more expensive, if still cheap in absolute terms, LOAD_ATTR
; plain name
for an argument is just a LOAD_FAST
), so if you're 100% sure you're never going to massage the argument before storage (e.g. no self.name = int(name)
), avoiding self
when you can will speed initialization a bit.
That said, it's rare to be that sure, so using self.name
is safer. You can always split the difference though even when massaging arguments, by doing something like:
self.name = name = int(name)
which stores back to both the attribute and the local (via DUP_TOP
and STORE_FAST
, two of the cheapest op codes in CPython), so you get the same massaged value by either means, and the cheap loads from the unqualified name.
Upvotes: 3
Reputation: 1500
It's a question of scope. In the example below, the variable 'name'
is only visible with in the method '__init__'
whereas the variable 'self.name_list'
can be used in any method within the class.
class Example :
def __init__ (self, name) :
self.name_list = [name] * 3
def show_variables (self) :
print (self.name_list)
print (name) # gives 'name' is not defined error
this = Example ('This example')
this.show_variables ()
Upvotes: -2