Reputation: 97
I would like to create a default value in this python class. But when I try and do it I get an error that says, "self is not defined"
I know the answer is something simple, yet it eludes me at the moment. Anyone know why I cannot add a default parameter here?
Thanks in advance for your replies!
class Sort(object):
def __init__(self, lst):
self.lst = lst
def halve(self, l = self.lst):### this line <--------------
n1 = l[:len(l) / 2]
n2 = l[len(l) /2:]
return (n1,n2)
Upvotes: 0
Views: 196
Reputation: 11
Others have shown how you can deal with your problem, but I would like to clear up exactly why your code isn't working.
Imagine you have the code:
def foo(obj, y = obj.x):
pass
This won't work for the same reason that the following won't work:
def foo(x, y = x+2):
pass
The key to your confusion, I think, is that there is nothing special about the name "self". It is easy to think that "self" is a key word that refers to the object (like in ruby, for instance), but it's not. In Python, object's methods automatically pass the object as the first parameter, and it just happens to be conventional to call this first parameter "self".
If you have a class, object, and method call like:
class A(object):
def foo(self, x, y):
pass
a = A()
a.foo(1, 2)
You can basically think of the method call as implicitly calling:
a.foo(a, 1, 2)
Which isn't the most careful way of putting it, but I think it makes the idea clear enough.
Upvotes: 0
Reputation: 1882
Even if it does not seem useful for your purpose, you can avoid using None
as a default placeholder, as you can use *args
to collect all arguments in one list:
def halve(self, *args):
if not args: # if arg is an empty list / no arguments given
lst = self.lst
else:
lst = args[0]
# code
or in one line:
def halve(self, *args):
lst = self.lst if not args else args[0]
# code
Upvotes: 0
Reputation:
Since it is one of the method's parameters, self
will only be defined inside Sort.halve
, not on the line that declares it. This means that you cannot access self.lst
until you are inside the method.
As a workaround, you can do something like this:
def halve(self, l=None):
if l is None:
l = self.lst
n1 = l[:len(l) / 2]
n2 = l[len(l) /2:]
return (n1,n2)
The above code assigns the l
parameter of Sort.halve
a default value of None
. When the method is invoked, it will use the if-statement to see if the caller supplied an argument for it or not. If so, it will keep l
equal to that. Otherwise, it will assign l
to self.lst
.
Upvotes: 1
Reputation: 23211
Unfortunately you need to designate a None
default and check inside the method whether it's been passed in
class Sort(object):
def __init__(self, lst):
self.lst = lst
def halve(self, l=None):
if l is None: l = self.lst
n1 = l[:len(l) / 2]
n2 = l[len(l) /2:]
return (n1,n2)
The parameters to a function are established when the function is created, not when it's called, so self.lst
doesn't yet exist.
Also, see the "Principle of Least Astonishment"
Upvotes: 3
Reputation: 54163
A better way to go about this, perhaps, would be:
def halve(self,l=None):
if l is None:
l = self.lst
# code
As an aside: please don't name variables l
el or O
oh or I
eye. They look like 1s and 0s in certain fonts and make things more difficult for everyone. If you want to signify that it's a generic list, use lst
just as you have for your class variable! Better, name it by what it signifies: is this a list of grades? grade_list
. Is it a list of numbers? numbers
. Even if it's just input_list
it's at least more readable than lst
and FAR more readable than l
Upvotes: 3