2015-12-14 9 views
5
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]) 

И ради эталонного - арг является:питон арга не работает, если он не имеет исходное положение

date_year = datetime.now().year 

для этого запроса на работу мне нужно ссылаться арг, как

.filter(fixture_datetime__year=args[0]) 

потому что если я использую

.filter(fixture_datetime__year=args) 

Я получаю сообщение об ошибке:

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

Я понимаю, что он думает, что это кортеж, даже если это только одна ценность, но когда я делаю следующее в терминале

type(date_year) 

я получаю класс обратно.

Почему у меня есть ссылка на позицию здесь, когда она выглядит как одно возвращаемое значение?

+1

'* args' есть * всегда * кортеж. –

+0

Я не понимаю, о чем вы спрашиваете. Кажется, вы уже ответили на все в своем вопросе. Если вы предоставите ровно один аргумент 'bar' для' foo (* args) 'then' args == (bar,)'. Но, читая ваше сообщение, вы уже это знали. – timgeb

+1

@timegb ОП спрашивает, почему, если он передает 'date_year' в вызове функции, почему он передается как кортеж длины 1, а не целое. –

ответ

4

* -предоставляемый аргумент всегда кортеж. Он фиксирует 0 или более дополнительных позиционных аргументов. Вы можете позвонить test_stats() функции с 3 или 20 или 100 дополнительными аргументами (за пределами явного team аргумента), и все они были бы часть args кортежа в функции:

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

Если вы хотите один дополнительных аргумент, сделать это ключевое слово аргумент с дозорным по умолчанию, как 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) 
     ) 
+0

Возможно, стоит обратить внимание на то, что 'foo (1)' будет возвращать '(1,)'. В случае, если кто-то считает, что единственным аргументом является исключение. – SuperBiasedMan

+1

@SuperBiasedMan: сделано, используя мое любимое целое число. –

1

Если вы знаете, что вы получаете дату в качестве второго аргумента, то явно определить его в подписи

def test_stats(team, date): 

Если вы можете пройти там тоже что-то другое, то использовать именованные аргументы

def test_stats(team, date=None, something_else=None): 

*args следует использовать только, если вы хотите, чтобы передать последовательность аргументов без создания последовательности заранее

def get_integers(*args): 
    return args 


>>> get_integers(1, 3, 4, 8, 9, 11) 
(1, 3, 4, 8, 9, 11) 

*args является кортежем, а **kwargs - это словарь.