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?
A solution using
@staticmethodwon’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 astaticmethod?”.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, doself.__class__.__makeDictinstead. This will look strange, because it is a strange thing to do – in Python, you almost never need to call a method asClass.method, and the only time you do (in code written beforesuperbecame available), usingself.__class__would be wrong.In similar vein, but the other way around, you could make it a
staticmethodand 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:
But, by far the best way is to realise you’re working in Python and not Java – put it outside the class.