views:

60

answers:

2

I wanted to write a method with an argument that defaults to a member variable like so:

def method(self, arg1=0, arg2=self.member):

Apparently this is not allowed. Should I write it a different way, or perhaps use a value of arg2 to signal when to use the member variable?

+5  A: 

Yep, use a sentinel -- e.g.:

class Foo(object):
    _sentinel = object()
    def method(self, arg1=0, arg2=_sentinel):
        if arg2 is self._sentinel: arg2 = self.member
        ...
    ...

note that you need barename _sentinel in the def, but self._sentinel in the body of the method (since that's how scoping works out in class bodies vs method bodies;-).

Alex Martelli
+1: Good answer, especially thoughts about `_sentiel` in method definition vs `self._sentiel` in method body.
gorsky
+2  A: 
def method(self, arg1=0, arg2=None):
    if arg2 is None:
        arg2 = self.member
    ...
Yaroslav
This stops the caller from being able to pass in `None` explicitly, which may be OK in some cases but not in others. The sentinel idiom I suggest in my A is minutely "heavier" (one more statement in class scope) but vastly more general.
Alex Martelli
+1: It's very, very rare to actually expect `None` as a legitimate value; it tends to violate one's expectations to have to say `foo( bar=None )`; why mention `bar` at all? This is simpler and covers well over 99.7% of the cases in practice.
S.Lott
@Alex, since it is probably python beginner's question, I provided simplest solution. In some way None is a sentinel too :)
Yaroslav
@S.Lott, there are many counterexamples to your claim that "passing None violates one's expectations": e.g., in `somedict.pop`, you have to specify `None` explicitly as the default value if that's what you want, else you'll get an exception when they key's missing.
Alex Martelli
I couldn't decide between Alex Martelli's and this, but this answer keeps my class a little simpler so I'm going with it.
phasetwenty
@Alex Martelli: While there may be many counterexamples, the "common" use cases don't encounter this situation very often. Indeed, the cases where `None` must be provided explicitly sometimes stem from overusing `None`. Often an exception should have been raised earlier rather than attempting to process instances of `None` as if they were "real" parts of the problem domain.
S.Lott