Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using None as parameter to keyword argument [duplicate]

Possible Duplicate:
python - returning a default value

I have a function in a class:

def foo(self, value = None):
    if value is None:
        return self.value
    self.value = value
    return self

This is a getter and setter combined into one, with the advantage that I can chain functions like this:

three = anInstanceOfMyClass.foo(3).bar().foo()

The problem appears when I do like this:

shouldBeNoneButIsThree = anInstanceOfMyClass.foo(3).foo(None).foo()

Here foo thinks that I did not pass an argument. I can avoid this by:

  1. Setting value to some strange object, like a random string
  2. Create an object instance in the constructor which value has as default value

Both seem a bit too much work, what is an easier way?

setting value to something

like image 303
Marcus Johansson Avatar asked Jun 12 '26 06:06

Marcus Johansson


2 Answers

You need to use a sentinel to detect that a default value was not set:

sentinel = object()

def foo(self, value=sentinel):
    if value is not sentinel:
        print("You passed in something else!")

This works because an instance of object() will always have it's own memory id and thus is will only return True if the exact value was left in place. Any other value will not register as the same object, including None.

You'll see different variants of the above trick in various different python projects. Any of the following sentinels would also work:

sentinel = []
sentinel = {}
like image 158
Martijn Pieters Avatar answered Jun 14 '26 18:06

Martijn Pieters


Using a sentinel object value is fairly common; this is what the library does in abcoll.py:

   __marker = object()

   def pop(self, key, default=__marker):
       ...
       if default is self.__marker:

Note that the sentinel object should be defined directly in the class.

like image 24
ecatmur Avatar answered Jun 14 '26 20:06

ecatmur



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!