Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

107
Views
Cuente cuántos argumentos pasaron como posicionales

Si tengo una funcion

 def foo(x, y): pass

¿Cómo puedo saber, desde dentro de la función, si y se pasó posicionalmente o con su palabra clave?

me gustaría tener algo como

 def foo(x, y): if passed_positionally(y): print('y was passed positionally!') else: print('y was passed with its keyword')

para que yo consiga

 >>> foo(3, 4) y was passed positionally >>> foo(3, y=4) y was passed with its keyword

Me doy cuenta de que originalmente no especifiqué esto, pero ¿es posible hacer esto mientras se conservan las anotaciones de tipo? La respuesta principal hasta ahora sugiere usar un decorador; sin embargo, eso no conserva el tipo de retorno

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Puedes crear un decorador, así:

 def checkargs(func): def inner(*args, **kwargs): if 'y' in kwargs: print('y passed with its keyword!') else: print('y passed positionally.') result = func(*args, **kwargs) return result return inner >>> @checkargs ...: def foo(x, y): ...: return x + y >>> foo(2, 3) y passed positionally. 5 >>> foo(2, y=3) y passed with its keyword! 5

Por supuesto, puede mejorar esto permitiendo que el decorador acepte argumentos. Por lo tanto, puede pasar el parámetro que desea verificar. Que sería algo como esto:

 def checkargs(param_to_check): def inner(func): def wrapper(*args, **kwargs): if param_to_check in kwargs: print('y passed with its keyword!') else: print('y passed positionally.') result = func(*args, **kwargs) return result return wrapper return inner >>> @checkargs(param_to_check='y') ...: def foo(x, y): ...: return x + y >>> foo(2, y=3) y passed with its keyword! 5

Creo que agregar functools.wraps preservaría las anotaciones, la siguiente versión también permite realizar la verificación de todos los argumentos (usando inspect ):

 from functools import wraps import inspect def checkargs(func): @wraps(func) def inner(*args, **kwargs): for param in inspect.signature(func).parameters: if param in kwargs: print(param, 'passed with its keyword!') else: print(param, 'passed positionally.') result = func(*args, **kwargs) return result return inner >>> @checkargs ...: def foo(x, y, z) -> int: ...: return x + y >>> foo(2, 3, z=4) x passed positionally. y passed positionally. z passed with its keyword! 9 >>> inspect.getfullargspec(foo) FullArgSpec(args=[], varargs='args', varkw='kwargs', defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={'return': <class 'int'>}) _____________HERE____________
over 4 years ago · Santiago Trujillo Report

0

Al final, si vas a hacer algo como esto:

 def foo(x, y): if passed_positionally(y): raise Exception("You need to pass 'y' as a keyword argument") else: process(x, y)

Puedes hacerlo:

 def foo(x, *, y): pass >>> foo(1, 2) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: foo() takes 1 positional argument but 2 were given >>> foo(1, y=2) # works

O solo permita que se pasen posicionalmente:

 def foo(x, y, /): pass >>> foo(x=1, y=2) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: foo() got some positional-only arguments passed as keyword arguments: 'x, y' >>> foo(1, 2) # works

Consulte PEP 570 y PEP 3102 para obtener más información.

over 4 years ago · Santiago Trujillo Report

0

Adaptado de la respuesta de @Cyttorak, aquí hay una forma de hacerlo que mantiene los tipos:

 from typing import TypeVar, Callable, Any, TYPE_CHECKING T = TypeVar("T", bound=Callable[..., Any]) from functools import wraps import inspect def checkargs() -> Callable[[T], T]: def decorate(func): @wraps(func) def inner(*args, **kwargs): for param in inspect.signature(func).parameters: if param in kwargs: print(param, 'passed with its keyword!') else: print(param, 'passed positionally.') result = func(*args, **kwargs) return result return inner return decorate @checkargs() def foo(x, y) -> int: return x+y if TYPE_CHECKING: reveal_type(foo(2, 3)) foo(2, 3) foo(2, y=3)

La salida es:

 $ mypy t.py t.py:27: note: Revealed type is 'builtins.int'
 $ python t.py x passed positionally. y passed positionally. x passed positionally. y passed with its keyword!
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!