que propias procedimientos opcionales metodos lista guardar funciones argumentos python arguments introspection

propias - lista de funciones de python



¿Puede enumerar los argumentos de palabra clave que recibe una función de Python? (5)

En Python 3.0:

>>> import inspect >>> import fileinput >>> print(inspect.getfullargspec(fileinput.input)) FullArgSpec(args=[''files'', ''inplace'', ''backup'', ''bufsize'', ''mode'', ''openhook''], varargs=None, varkw=None, defaults=(None, 0, '''', 0, ''r'', None), kwonlyargs=[], kwdefaults=None, annotations={})

Tengo un dict, que necesito para pasar clave / valores como argumentos de palabra clave .. Por ejemplo ..

d_args = {''kw1'': ''value1'', ''kw2'': ''value2''} example(**d_args)

Esto funciona bien, pero si hay valores en el dictus d_args que no son aceptados por la función de example , obviamente muere ... Digamos, si la función de ejemplo se define como def example(kw2):

Esto es un problema ya que no controlo ni la generación de los d_args , ni la función de example . Ambos vienen de módulos externos, y el example solo acepta algunos de los argumentos de palabras clave del dict ..

Idealmente, solo lo haría

parsed_kwargs = feedparser.parse(the_url) valid_kwargs = get_valid_kwargs(parsed_kwargs, valid_for = PyRSS2Gen.RSS2) PyRSS2Gen.RSS2(**valid_kwargs)

Probablemente solo filtre el dict, de una lista de argumentos válidos de palabras clave, pero me preguntaba: ¿hay alguna forma de enumerar programáticamente los argumentos de las palabras clave que toma una función específica?


Esto imprimirá nombres de todos los argumentos pasables, palabra clave y no palabras clave:

def func(one, two="value"): y = one, two return y print func.func_code.co_varnames[:func.func_code.co_argcount]

Esto se debe a que los primeros co_varnames son siempre parámetros (a continuación están las variables locales, como y en el ejemplo anterior).

Entonces ahora podrías tener una función:

def getValidArgs(func, argsDict): ''''''Return dictionary without invalid function arguments.'''''' validArgs = func.func_code.co_varnames[:func.func_code.co_argcount] return dict((key, value) for key, value in argsDict.iteritems() if key in validArgs)

Que luego podría usar así:

>>> func(**getValidArgs(func, args))

EDITAR : una pequeña adición: si realmente solo necesita argumentos de palabra clave de una función, puede usar el atributo func_defaults para extraerlos:

def getValidKwargs(func, argsDict): validArgs = func.func_code.co_varnames[:func.func_code.co_argcount] kwargsLen = len(func.func_defaults) # number of keyword arguments validKwargs = validArgs[-kwargsLen:] # because kwargs are last return dict((key, value) for key, value in argsDict.iteritems() if key in validKwargs)

Ahora puede llamar a su función con args conocidos, pero extrae kwargs, por ejemplo:

func(param1, param2, **getValidKwargs(func, kwargsDict))

Esto supone que func no usa *args o **kwargs magic en su firma.


Extendiendo la respuesta de DzinX:

argnames = example.func_code.co_varnames[:func.func_code.co_argcount] args = dict((key, val) for key,val in d_args.iteritems() if key in argnames) example(**args)


Para una solución de Python 3, puede usar inspect.signature y filter de acuerdo con el tipo de parámetros que le gustaría conocer.

Tomando una función de muestra con parámetros de palabras clave posicionales o de palabra clave, palabra clave única, var posicional y var:

def spam(a, b=1, *args, c=2, **kwargs): print(a, b, args, c, kwargs)

Puede crear un objeto de firma para él:

from inspect import signature sig = signature(spam)

y luego filtra con una lista de comprensión para descubrir los detalles que necesitas:

>>> # positional or keyword >>> [p.name for p in sig.parameters.values() if p.kind == p.POSITIONAL_OR_KEYWORD] [''a'', ''b''] >>> # keyword only >>> [p.name for p in sig.parameters.values() if p.kind == p.KEYWORD_ONLY] [''c'']

y, de forma similar, para los posicionales var utilizando p.VAR_POSITIONAL y la palabra clave var con VAR_KEYWORD .

Además, puede agregar una cláusula al si para verificar si existe un valor predeterminado al verificar si p.default es igual a p.empty .


Un poco mejor que inspeccionar el objeto de código directamente y calcular las variables es usar el módulo de inspección.

>>> import inspect >>> def func(a,b,c=42, *args, **kwargs): pass >>> inspect.getargspec(func) ([''a'', ''b'', ''c''], ''args'', ''kwargs'', (42,))

Si desea saber si es invocable con un conjunto particular de argumentos, necesita los argumentos sin un predeterminado ya especificado. Estos se pueden obtener por:

def getRequiredArgs(func): args, varargs, varkw, defaults = inspect.getargspec(func) if defaults: args = args[:-len(defaults)] return args # *args and **kwargs are not required, so ignore them.

Entonces, una función para decir lo que te falta de tu dict particular es:

def missingArgs(func, argdict): return set(getRequiredArgs(func)).difference(argdict)

Del mismo modo, para verificar argumentos no válidos, use:

def invalidArgs(func, argdict): args, varargs, varkw, defaults = inspect.getargspec(func) if varkw: return set() # All accepted return set(argdict) - set(args)

Y entonces una prueba completa si es invocable es:

def isCallableWithArgs(func, argdict): return not missingArgs(func, argdict) and not invalidArgs(func, argdict)

(Esto solo es bueno en lo que respecta al análisis sintáctico arg de Python. Evidentemente, ningún control de tiempo de ejecución para valores inválidos en kwargs no se puede detectar).