una subclases privados poo objetos objeto metodos llamar lista definir como clase atributos python decorator introspection python-datamodel

subclases - poo python 3



Obtener nombres de parámetros de método en python (11)

Dada la función de python:

def aMethod(arg1, arg2): pass

¿Cómo puedo extraer el número y los nombres de los argumentos? Es decir. dado que tengo una referencia a func, quiero que la función [algo] vuelva ("arg1", "arg2")

El escenario de uso para esto es que tengo un decorador, y deseo utilizar los argumentos del método en el mismo orden en que aparecen para la función real como una clave. Es decir. ¿Cómo se vería el decorador que imprimió "a, b" cuando llamo a un método ("a", "b")


¿Qué pasa con dir() y vars() ahora?

Parece que está haciendo exactamente lo que se le pregunta de forma sencilla ...

(Desde el interior de la función / método)


Actualización para la respuesta de Brian. Si la función en Python 3 tiene argumentos de palabra clave, entonces necesita usar inspect.getfullargspec :

def yay(a, b=10, *, c=20, d=30): pass inspect.getfullargspec(yay)

cede esto:

FullArgSpec(args=[''a'', ''b''], varargs=None, varkw=None, defaults=(10,), kwonlyargs=[''c'', ''d''], kwonlydefaults={''c'': 20, ''d'': 30}, annotations={})


Aquí hay algo que creo que funcionará para lo que quieras, usando un decorador.

class LogWrappedFunction(object): def __init__(self, function): self.function = function def logAndCall(self, *arguments, **namedArguments): print "Calling %s with arguments %s and named arguments %s" %/ (self.function.func_name, arguments, namedArguments) self.function.__call__(*arguments, **namedArguments) def logwrap(function): return LogWrappedFunction(function).logAndCall @logwrap def doSomething(spam, eggs, foo, bar): print "Doing something totally awesome with %s and %s." % (spam, eggs) doSomething("beans","rice", foo="wiggity", bar="wack")

Ejecútelo, producirá el siguiente resultado:

C:/scripts>python decoratorExample.py Calling doSomething with arguments (''beans'', ''rice'') and named arguments {''foo'': ''wiggity'', ''bar'': ''wack''} Doing something totally awesome with beans and rice.


Como las respuestas son un poco antiguas y tuve que hacer algunas modificaciones para que funcionen para Python3, estoy agregando mi versión:

def _get_args_dict(fn, args, kwargs): args_names = fn.__code__.co_varnames[:fn.__code__.co_argcount] return {**dict(zip(args_names, args)), **kwargs}

El método devuelve un diccionario que contiene tanto args como kwargs.


Creo que lo que estás buscando es el método local:

In [6]: def test(a, b):print locals() ...: In [7]: test(1,2) {''a'': 1, ''b'': 2}


Devuelve una lista de nombres de argumento, se encarga de los parciales y las funciones regulares:

def get_func_args(f): if hasattr(f, ''args''): return f.args else: return list(inspect.signature(f).parameters)


Eche un vistazo al módulo de inspect : esto hará la inspección de las diversas propiedades del objeto de código por usted.

>>> inspect.getargspec(aMethod) ([''arg1'', ''arg2''], None, None, None)

Los otros resultados son el nombre de las variables * args y ** kwargs, y los valores predeterminados proporcionados. es decir.

>>> def foo(a,b,c=4, *arglist, **keywords): pass >>> inspect.getargspec(foo) ([''a'', ''b'', ''c''], ''arglist'', ''keywords'', (4,))

Tenga en cuenta que algunos callables pueden no ser introspectibles en ciertas implementaciones de Python. Por ejemplo, en CPython, algunas funciones incorporadas definidas en C no proporcionan metadatos sobre sus argumentos. Como resultado, obtendrá ValueError en el caso de que use inspect.getargspec() con una función incorporada.

Desde Python 3.3, también puede usar inspect.signature() para conocer la firma de llamada de un objeto invocable:

>>> inspect.signature(foo) <Signature (a, b, c=4, *arglist, **keywords)>


En CPython, la cantidad de argumentos es

aMethod.func_code.co_argcount

y sus nombres están en el comienzo de

aMethod.func_code.co_varnames

Estos son detalles de implementación de CPython, por lo que probablemente no funcione en otras implementaciones de Python, como IronPython y Jython.

Una forma portátil de admitir argumentos "paso a paso" es definir su función con la func(*args, **kwargs) . Esto se usa mucho en, por ejemplo, matplotlib, donde la capa API externa pasa muchos argumentos clave a la API de nivel inferior.


En Python 3. + con el objeto Signature en la mano, una forma fácil de obtener una asignación entre los nombres de args a valores, es usar el método bind() Signature.

Por ejemplo, aquí hay un decorador para imprimir un mapa como ese:

import inspect def decorator(f): def wrapper(*args, **kwargs): bound_args = inspect.signature(f).bind(*args, **kwargs) bound_args.apply_defaults() print(dict(bound_args.arguments)) return f(*args, **kwargs) return wrapper @decorator def foo(x, y, param_with_default="bars", **kwargs): pass foo(1, 2, extra="baz") # This wil print: {''kwargs'': {''extra'': ''baz''}, ''param_with_default'': ''bars'', ''y'': 2, ''x'': 1}


En un método de decorador, puede enumerar los argumentos del método original de esta manera:

import inspect, itertools def my_decorator(): def decorator(f): def wrapper(*args, **kwargs): # if you want arguments names as a list: args_name = inspect.getargspec(f)[0] print(args_name) # if you want names and values as a dictionary: args_dict = dict(itertools.izip(args_name, args)) print(args_dict) # if you want values as a list: args_values = args_dict.values() print(args_values)

Si los **kwargs son importantes para ti, entonces será un poco complicado:

def wrapper(*args, **kwargs): args_name = list(OrderedDict.fromkeys(inspect.getargspec(f)[0] + kwargs.keys())) args_dict = OrderedDict(list(itertools.izip(args_name, args)) + list(kwargs.iteritems())) args_values = args_dict.values()

Ejemplo:

@my_decorator() def my_function(x, y, z=3): pass my_function(1, y=2, z=3, w=0) # prints: # [''x'', ''y'', ''z'', ''w''] # {''y'': 2, ''x'': 1, ''z'': 3, ''w'': 0} # [1, 2, 3, 0]


Python 3.5+

Anuncio de depreciación: inspect.getargspec () está en desuso, use inspect.signature () en su lugar

Entonces previamente:

func_args = inspect.getargspec(function).args

Ahora:

func_args = list(inspect.signature(function).parameters.keys())

Probar:

''arg'' in list(inspect.signature(function).parameters.keys())

Dado que tenemos la función ''función'' que toma el argumento ''arg'', esto se evaluará como Verdadero, de lo contrario como Falso.

Ejemplo de la consola de python:

Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 07:18:10) [MSC v.1900 32 bit (Intel)] on win32 >>> import inspect >>> ''iterable'' in list(inspect.signature(sum).parameters.keys()) True