1

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?

2 Answers 2

6

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)
Sign up to request clarification or add additional context in comments.

3 Comments

But CSVDescription = __makeDict(__CSVDescription) doesn't work, when I add @staticmethod. Then I get the error TypeError: 'staticmethod' object is not callable.
@wewa which Python version are you using?
I am using Python version 2.5.1
3

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)

1 Comment

yes, you're right, i've made mistakes and i have deleted my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.