Reputation: 1678
I've got a question about defining functions and the self-parameter in python.
There is following code.
class Dictionaries(object):
__CSVDescription = ["ID", "States", "FilterTime", "Reaction", "DTC", "ActiveDischarge"]
def __makeDict(Lst):
return dict(zip(Lst, range(len(Lst))))
def getDict(self):
return self.__makeDict(self.__CSVDescription)
CSVDescription = __makeDict(__CSVDescription)
x = Dictionaries()
print x.CSVDescription
print x.getDict()
x.CSVDescription
works fine. But print x.getDict()
returns an error.
TypeError: __makeDict() takes exactly 1 argument (2 given)
I can add the self
-parameter to the __makeDict()
method, but then print x.CSVDescription
wouldn't work.
How do I use the self
-parameter correctly?
Upvotes: 1
Views: 268
Reputation: 35089
A solution using @staticmethod
won't work here because calling the method from the class body itself doesn't invoke the descriptor protocol (this would also be a problem for normal methods if they were descriptors - but that isn't the case until after the class definition has been compiled). There are four major options here - but most of them could be seen as some level of code obfuscation, and would really need a comment to answer the question "why not just use a staticmethod
?".
The first is, as @Marcus suggests, to always call the method from the class, not from an instance. That is, every time you would do self.__makeDict
, do self.__class__.__makeDict
instead. This will look strange, because it is a strange thing to do - in Python, you almost never need to call a method as Class.method
, and the only time you do (in code written before super
became available), using self.__class__
would be wrong.
In similar vein, but the other way around, you could make it a staticmethod
and invoke the descriptor protocol manually in the class body - do: __makeDict.__get__(None, Dictionaries)(__lst)
.
Or, you could detect yourself what context its being called from by getting fancy with optional arguments:
def __makeDict(self, Lst=None):
if Lst is None:
Lst = self
...
But, by far the best way is to realise you're working in Python and not Java - put it outside the class.
def _makeDict(Lst):
...
class Dictionaries(object):
def getDict(self):
return _makeDict(self.__CSVDescription)
CSVDescription = _makeDict(__CSVDescription)
Upvotes: 3
Reputation: 5135
In python, the self
parameter is implicitly passed to instance methods, unless the method is decorated with @staticmethod
.
In this case, __makeDict
doesn't need a reference to the object itself, so it can be made a static method so you can omit the self
:
@staticmethod
def __makeDict(Lst): # ...
def getDict(self):
return self.__makeDict(self.__CSVDescription)
Upvotes: 6