Как передать аргументы функции - PullRequest
2 голосов
/ 02 ноября 2019

Есть ли в python способ получить аргументы, переданные вызывающей стороной в функцию? Вот что я пытаюсь сделать:

# function
def repeat(self, min=None, max=None, optional=False):
    do_something()

Мне нужно сделать что-то по-другому, в зависимости от того, передан ли ему один или несколько аргументов. Например:

r.repeat('hello').repeat(2,None)

Необходимо различать:

r.repeat('hello').repeat(2) # only one arg passed

Я думал, что locals может быть хорошим местом для начала, но он берет аргумент по умолчанию из функциипоэтому не работает для моих целей:

{'_max': None, '_min': 2, 'discrete': [], 'optional': False, 'max': None, 'min': 2, 'self': r'(hello)'}

Другими словами, max не должен отображаться в качестве одного из аргументов. Возможно ли это сделать в python? Я также пытался использовать inspect, но это, похоже, также показывает значения по умолчанию:

(Pdb) inspect.getargvalues(f)
ArgInfo(args=['self', 'min', 'max', 'optional', 'discrete'], varargs=None, keywords=None, locals={'pdb': <module 'pdb' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/pdb.py'>,
 '_max': None, '_min': 2, 'discrete': [], 'optional': False, 'max': None, 'min': 2, 'self': r'(hello)', 'f': <frame object at 0x101e2de68>})

1 Ответ

1 голос
/ 02 ноября 2019

Я думаю, что есть более простые решения вашей проблемы. Самый простой способ, который я знаю, - это иметь значение по умолчанию, которое невозможно передать в качестве фактического аргумента. Создайте фиктивный объект и используйте его по умолчанию:

dummy_default = object()

def my_function(x=dummy_default):
    actual_x = None if x is dummy_default else x
    # ...

Таким образом, actual_x будет None, либо если аргумент не передан, либо None передан явно, но вы можете различитьмежду этими случаями, проверяя x is dummy_default.


Вы также можете использовать *vargs:

def my_function(*vargs):
    if len(vargs) > 1:
        raise TypeError('Too many arguments')
    x = vargs[0] if len(vargs) >= 1 else None
    # ...

Выражение len(vargs) == 0 сообщит вам, не был ли передан аргумент.

Этот способ немного хуже, потому что заставить ключевые аргументы работать тоже сложнее, вы не получите полезной подсказки аргумента, если используете IDE, и вам придется самостоятельно обрабатывать ошибки для неправильных чиселаргументов.

...