2015-08-22 4 views
3

Я новичок в Python, но я знаю, что могу разрешить переменное число из нескольких аргументов в функции, используя *args.Python: «Несколько» нескольких аргументов в функции

Этот скрипт ищет word в любом количестве строки *sources:

def find(word, *sources): 
    for i in list(sources): 
     if word in i: 
      return True 

source1 = "This is a string" 
source2 = "This is Wow!" 

if find("string", source1, source2) is True: 
    print "Succeed" 

Однако, можно указать «несколько» несколько аргументов (*args) в одной функции? В этом случае это будет искать несколько *words в нескольких *sources.

Как и в, образно:

if find("string", "Wow!", source1, source2) is True: 
    print "Succeed" 
else: 
    print "Fail" 

Как я могу сделать сценарий усмотреть, что предназначено быть word, и что, как предполагается, будет source?

+0

Если у вас несколько аргументов, как вы могли бы назвать эту функцию? Как python узнает, в какую из них можно вставить значение? –

ответ

5

Нет, вы не можете, потому что вы не можете отличить, где останавливается один тип элемента, а другой запускается.

Пусть ваш первый аргумент принимать либо одну строку или последовательность, вместо:

def find(words, *sources): 
    if isinstance(words, str): 
     words = [words] # make it a list 
    # Treat words as a sequence in the rest of the function 

Теперь вы можете называть его либо как:

find("string", source1, source2) 

или

find(("string1", "string2"), source1, source2) 

По проходя в последовательности явно, вы можете отличить ее от нескольких источников, поскольку она по сути всего одна аргумент.

+1

@VigneshKalai: в этом случае избиратель может быть более полезным, помещая вопрос как дубликат. Я сомневаюсь, что это была их мотивация. –

+0

Если мне предвидится более одного типа аргументов, мой опыт говорит мне полностью избегать магов '*' и '**'. Это становится беспорядочным, когда вы используете аргументы ключевого слова и не чувствуете себя полностью «согласованными», как в вашем примере: слова должны передаваться как итеративные, источники как varargs. Возможно, он не выглядит таким питоническим, чтобы писать '' def find (слова, источники) '', но в долгосрочной перспективе последовательность и чистота превосходят классный синтаксис. – bgusach

2

Обычным решением для «множественных источников» является то, что *args будет первым кратным, а вторым кратным является кортеж.

>>> def search(target, *sources): 
     for i, source in enumerate(sources): 
      if target in source: 
       print('Found %r in %r' % (i, source)) 
       return 
     print('Did not find %r' % target) 

Вы найдете другие примеры такого рода дизайн API, используемый на протяжении основного языка Python:

>>> help(str.endswith) 
Help on method_descriptor: 

endswith(...) 
    S.endswith(suffix[, start[, end]]) -> bool 

    Return True if S ends with the specified suffix, False otherwise. 
    With optional start, test S beginning at that position. 
    With optional end, stop comparing S at that position. 
    suffix can also be a tuple of strings to try. 

>>> 'index.html'.endswith(('.xml', '.html', '.php'), 2) 
True   
    >>> search(10, (5, 7, 9), (6, 11, 15), (8, 10, 14), (13, 15, 17)) 
    Found 2 in (8, 10, 14) 

Обратите внимание, что суффикса может быть tuple of strings to try.

+1

Спасибо за это! – Winterflags

+0

Я не вижу, как это отвечает на вопрос, что OP эффективно хочет обрабатывать '* target' _and_' * sources'. – martineau

Смежные вопросы