1

I'm trying to use

def my_function(a,b)

If I try to print function like this print(my_function()), when values start from none, I get "missing 2 required positional arguments"

I want to use default value so when I use, print(my_function()), a=10 and b=a.

So I tried

def my_function(a=10,b=a)

and I got a not defined.

I don't want to define a before with global.

Is it possible? or something like this

def my_function(a,b)
    if a == None:
        a = 10
    if b == None:
        b = a

This didn't work either when I used print(my_function()).

3 Answers 3

5

You can set the default to None:

def my_function(a=10, b=None):
    if b is None:
        b = a

Here the default for a is 10, and b is set to a if left to the default value.

If you need to accept None as well, pick a different, unique default to act as a sentinel. An instance of object() is an oft-used convention:

_sentinel = object()

def my_function(a=10, b=_sentinel):
    if b is _sentinel:
        b = a

Now you can call my_function(11, None) and b will be set to None, call it without specifying b (e.g. my_function() or my_function(42), and b will be set to whatever a was set to.

Unless a parameter has a default (e.g. is a keyword parameter), they are required.

Sign up to request clarification or add additional context in comments.

5 Comments

Ellipsis is sometimes a good sentinel value when you need to accept None. It's built into Python but is used for hardly anything outside of writing __getitem__ and __setitem__ methods.
@kindall: I prefer being explicit about this. Ellipsis is a big documentation WTF; it looks out of place, and it is not clear that you are just using it as a sentinel. The same applies to NotImplemented.
Really, no sentinel value is very self-documenting if you're just going to replace it with some other value (e.g. empty list) in the code itself. I guess you could name your sentinel something like DefaultEmptyList or whatever.
@kindall: _sentinel is clearly documenting what function it serves. Ellipsis does not.
@kindall To get the name in the repr, you can use a class: class _Sentinel: pass _sentinel = _Sentinel() ... help(my_function) -> ... my_function(a=10, b=<..._Sentinel object at 0x...>)
0

This function my_function(a,b) expected two positional arguments without default value so It can't be called without them passed

So the main question how can we pass two argument so that second is set to first if not passed

There are two way for this:

kwargs unpacking

def my_function(a=10, **kwargs):
    b = kwargs.get('b', a)

sentinel as default Value

_sentinel = object()
def my_function(a=10, b=_sentinel):
    if b is _sentinel:
        b = a

Comments

0

Hum! I thing you can't define my_function like this. But you can use a decorator to hide the default values computation.

For example:

import functools


def my_decorator(f):
    @functools.wraps(f)
    def wrapper(a=10, b=None):
        if b is None:
            b = a
        return f(a, b)
    return wrapper

You can then define your function like this:

@my_decorator
def my_function(a, b):
    return (a, b)

You can use your function with zero, one or two parameters:

>>> print(my_function())
(10, 10)
>>> print(my_function(5))
(5, 5)
>>> print(my_function(5, 12))
(5, 12)

Comments

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.