views:

387

answers:

4

Hi,

I have been writing Python code for only a couple of weeks, so I'm still figuring out the lay of the land. But let's say I have a method that MAY be called on by a 'user' on occasion as well as used HEAVILY internally (ie, the arguments have already been checked before the call). Here is what I am currently doing:

#The method the 'user' should call:
def do_something(self, arg1, arg2, arg3):
    #write code to do error checking on arg1, agr2, arg3
    #raise exceptions, return codes, etc: depends on whether you are an explicit lover
    #or an implicit lover, it seems. :-)
    ... error checking code here...
    #Now call the 'brother' method that does the real work.
    return self._do_something(self, arg1, arg2, arg3, arg3)

#The method other private methods should call with already validated parameters
def _do_something(self, arg1, arg2, arg3, arg3):
    #don't do error checking on the parameters. get to work...
    ... do what you do...
    return whatever you're supposed to return

This seems logical to me. Is there a better Python-ish way to do this?

Paul

A: 

There is no "true" support for private members in python, but the pythonic way to indicate a member as private is to use two leading underscores. In your case, __do_something.

For further details, see python.org - classes

Marcin
True private fields can be created by adding functions to an object inside its own __init__ that refer to local variables using a closure. Although not many people seem to know this.
recursive
-1: Two underscores are rarely used in practice, the usual pythonic way is a single underscore.
nikow
@nikow, you're simply wrong here. Two underscores is the way to do "private" in Python, and it even has language support for it (the name gets munged from `__foo` to `_ClassName__foo`). You may be thinking of Python's *convention* (and it's only that) for "protected" members, which does use only a single underscore.
Peter Hansen
A: 

I'm just learning python myself (and enjoying it) but I think that's the way to do it. However, the private method should have two underscores and called like 'self.__do_something()'.

thethinman
+2  A: 

That is fine. The call to the "brother" method is wrong in your code, though. You should do it like this:

# Now call the 'brother' method that does the real work.
return self._do_something(arg1, arg2, arg3, arg3)

That is, you should call it "through" the self reference, since it's an object method and not a global function.

unwind
Yes, thanks for that.
TallPaul
Edited method call as suggested.
TallPaul
A: 

well, unless the error checking code is very expensive, I would have only one method, which always does the error checking. It may repeat some checks, but it does offer you more security, and it may come in handy if someone inherits from your class.

If later on you need performance you can always cache results or do something else.

Mario
In my case, I am working on a re-write of a biopython module. There is a method to download a file from FTP based on a four character code. A user can either call it individually with one file to download, or ask for a batch of 57000+ files to download based on the codes written in an index file. If the user calls it, I need to check the code they pass in. If the codes comes from the index file that has the 57000 codes, no need to check to make sure they have a valid format!
TallPaul
in that case I guess it makes sense to separate both methods. I would use different names though, to make clear that one method is used with user-input and the other not.
Mario