Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python args not working unless it has a position reference [duplicate]

Tags:

python

args

def test_stats(team, *args):

    if not args:
          [do some stuff]
    else:

        team_fixtures = (Fixtures.objects.filter(home_team=team_details.id) | Fixtures.objects.filter(away_team=team_details.id))/
.filter(fixture_datetime__lt=datetime.now()).filter(fixture_datetime__year=args[0])

And for reference sake - args is:

date_year = datetime.now().year

for this query to work i need to reference args as

.filter(fixture_datetime__year=args[0])

because if I use

.filter(fixture_datetime__year=args)

I get the error:

int() argument must be a string, a bytes-like object or a number, not 'tuple'

I understand that it thinks it's a tuple even though it's only one value but when I do the following in terminal

type(date_year)

I get class back.

Why do I have to reference position here when it looks to be just one value returning?

like image 971
purchas Avatar asked Dec 14 '15 14:12

purchas


People also ask

Are Python arguments passed by reference or value?

All parameters (arguments) in the Python language are passed by reference. It means if you change what a parameter refers to within a function, the change also reflects back in the calling function.

What is the use of * args in Python?

*args allows us to pass a variable number of non-keyword arguments to a Python function. In the function, we should use an asterisk ( * ) before the parameter name to pass a variable number of arguments.

What datatype are the * args stored when passed into a function?

As what datatype are the *args stored, when passed into a function? List.

Does Python function change parameter value?

If you pass immutable arguments like integers, strings or tuples to a function, the passing acts like call-by-value. The object reference is passed to the function parameters. They can't be changed within the function, because they can't be changed at all, i.e. they are immutable.


1 Answers

The *-prefixed argument is always a tuple. It captures 0 or more extra positional arguments. You can call your test_stats() function with 3 or 20 or 100 extra arguments (beyond the explicit team argument), and they all would be part of the args tuple in the function:

>>> def foo(*args): return args
...
>>> foo()
()
>>> foo(42)
(42,)
>>> foo(1, 2, 3)
(1, 2, 3)

If you wanted one optional argument, make it a keyword argument with a sentinel default, like None:

def test_stats(team, optional=None):
    if optional is None:
        # ...
    else:
        team_fixtures = (
            Fixtures.objects.filter(home_team=team_details.id) |
            Fixtures.objects.filter(away_team=team_details.id))
                .filter(fixture_datetime__lt=datetime.now())
                .filter(fixture_datetime__year=optional)
        )
like image 50
Martijn Pieters Avatar answered Oct 13 '22 01:10

Martijn Pieters