Come posso trovare il numero di argomenti di una funzione Python?


163

Come posso trovare il numero di argomenti di una funzione Python? Devo sapere quanti argomenti normali ha e quanti argomenti nominati.

Esempio:

def someMethod(self, arg1, kwarg1=None):
    pass

Questo metodo ha 2 argomenti e 1 argomento denominato.


43
la domanda è pienamente giustificata; se non lo fosse (dato che puoi sempre leggere la fonte), non ci sarebbe alcuna giustificazione per il inspectmodulo libreria standard.
flusso

Molte lingue implementano almeno una caratteristica ingiustificata. Il inspectmodulo ha molte altre funzionalità, quindi non è giusto dire che l'intero modulo sarebbe ingiustificato se una particolare funzione fosse presente. Inoltre, è facile vedere come questa funzione potrebbe essere utilizzata male. (Vedi stackoverflow.com/questions/741950 ). Detto questo, è una caratteristica utile, soprattutto per la scrittura di decoratori e altre funzioni che operano sulla funzione.
user1612868

Risposte:


131

La risposta precedentemente accettata è stata deprecata a partire da Python 3.0. Invece di usare inspect.getargspecora dovresti optare per la Signatureclasse che l'ha sostituita.

La creazione di una firma per la funzione è facile tramite la signaturefunzione :

from inspect import signature

def someMethod(self, arg1, kwarg1=None):
    pass

sig = signature(someMethod)

Ora puoi visualizzare rapidamente i suoi parametri strinserendolo:

str(sig)  # returns: '(self, arg1, kwarg1=None)'

oppure puoi anche ottenere una mappatura dei nomi degli attributi agli oggetti parametro tramite sig.parameters.

params = sig.parameters 
print(params['kwarg1']) # prints: kwarg1=20

Inoltre, è possibile chiamare lensu sig.parametersdi vedere anche il numero di argomenti di questa funzione richiede:

print(len(params))  # 3

Ogni voce nella paramsmappatura è in realtà un Parameteroggetto che ha ulteriori attributi che ti semplificano la vita. Ad esempio, afferrare un parametro e visualizzarne il valore predefinito ora è facilmente eseguibile con:

kwarg1 = params['kwarg1']
kwarg1.default # returns: None

allo stesso modo per il resto degli oggetti contenuti in parameters.


Per quanto riguarda gli 2.xutenti di Python , sebbene inspect.getargspec non sia deprecato, la lingua sarà presto :-). La Signatureclasse non è disponibile nella 2.xserie e non lo sarà. Quindi devi ancora lavorare con inspect.getargspec.

Per quanto riguarda la transizione tra Python 2 e 3, se hai codice che si basa sull'interfaccia di getargspecin Python 2 e il passaggio a signaturein 3è troppo difficile, hai la preziosa opzione di usare inspect.getfullargspec. Offre un'interfaccia simile a getargspec(un singolo argomento richiamabile) al fine di afferrare gli argomenti di una funzione gestendo anche alcuni casi aggiuntivi che getargspecnon:

from inspect import getfullargspec

def someMethod(self, arg1, kwarg1=None):
    pass

args = getfullargspec(someMethod)

Come con getargspec, getfullargspecrestituisce un NamedTupleche contiene gli argomenti.

print(args)
FullArgSpec(args=['self', 'arg1', 'kwarg1'], varargs=None, varkw=None, defaults=(None,), kwonlyargs=[], kwonlydefaults=None, annotations={})

1
Prego @ GeorgSchölly. Sono stato sorpreso da una domanda popolare come questa che offriva soluzioni che erano deprecate o in fondo subdole (sbirciare co_argcountnell'attributo.)
Dimitris Fasarakis Hilliard

1
getfullargspecnon è implementato in Python 2.x, è necessario utilizzarlogetargspec
Peter Gibson,

getargspecnon funziona con le funzioni integrate: getargspec(open)TypeError: <built-in function open> is not a Python functionVedere questa risposta per alcune idee ...
Starfry

Nel tuo ultimo esempio, quando print(args)lo fai non defaults=(None,)capisci defaults=None.
Seanny123,

esiste un modo per ottenere il conteggio dei parametri originale per una funzione che è stata decorata dopo la decorazione ..?
Gulats,

117
import inspect
inspect.getargspec(someMethod)

vedere il modulo di ispezione


5
Generalmente quello che vuoi, ma questo non funziona per le funzioni integrate. L'unico modo per sapere di ottenere queste informazioni per i builtin è analizzare la loro stringa di documenti , che è fugace ma fattibile.
Cerin,


Esiste una soluzione che non è obsoleta in Python 3?
hlin117,

1
Se segui il link vedrai che consiglia di utilizzare inspect.signature- docs.python.org/3/library/inspect.html#inspect.signature
coderforlife

Ho pubblicato un altro possibile approccio per le funzioni integrate senza analizzare la documentazione qui: stackoverflow.com/questions/48567935/…
HelloWorld,

31
someMethod.func_code.co_argcount

oppure, se il nome della funzione corrente non è definito:

import sys

sys._getframe().func_code.co_argcount

4
@elyase, basta fare: dir(someMethod)-> 'func_code'; Vai oltre: dir(someMethod.func_code)-> 'co_argcount'; È possibile utilizzare il built-in dir()per determinare i metodi disponibili di un oggetto.

@elyase Anche io ero gentile, quindi ho trovato questo docs.python.org/2/library/inspect.html#types-and-members
rodripf

Per supportare Python 3:six.get_function_code(someMethod).co_argcount
noisecapella,

8
@noisecapella non è necessario un modulo di terze parti, quando puoi semplicemente farlosome_method.__code__.co_argcount
vallentin

1
In generale, non dovresti sbirciare all'interno dell'oggetto funzione per guardare queste cose. co_argcountviene utilizzato internamente durante la valutazione dell'oggetto codice. Quello che sto cercando di dire è che non esiste alcuna garanzia che questi attributi non cambieranno da una versione all'altra.
Dimitris Fasarakis Hilliard,

16

inspect.getargspec ()

Ottieni i nomi e i valori predefiniti degli argomenti di una funzione. Viene restituita una tupla di quattro cose: (args, varargs, varkw, default). args è un elenco dei nomi degli argomenti (può contenere elenchi nidificati). varargs e varkw sono i nomi degli argomenti * e ** o Nessuno. defaults è una tupla di valori degli argomenti predefiniti o Nessuno se non ci sono argomenti predefiniti; se questa tupla ha n elementi, corrispondono agli ultimi n elementi elencati in args.

Modificato nella versione 2.6: restituisce una tupla ArgSpec denominata (args, varargs, parole chiave, valori predefiniti).

Vedi can-you-list-the-keyword-argomenti-a-python-function-riceve .


5

In aggiunta a quanto sopra, ho anche visto che la maggior parte delle volte la funzione help () aiuta davvero

Ad esempio, fornisce tutti i dettagli sugli argomenti che prende.

help(<method>)

dà il seguito

method(self, **kwargs) method of apiclient.discovery.Resource instance
Retrieves a report which is a collection of properties / statistics for a specific customer.

Args:
  date: string, Represents the date in yyyy-mm-dd format for which the data is to be fetched. (required)
  pageToken: string, Token to specify next page.
  parameters: string, Represents the application name, parameter name pairs to fetch in csv as app_name1:param_name1, app_name2:param_name2.

Returns:
  An object of the form:

    { # JSON template for a collection of usage reports.
    "nextPageToken": "A String", # Token for retrieving the next page
    "kind": "admin#reports#usageReports", # Th

Sarebbe bene che le persone lasciassero un commento su ciò che non va in un post piuttosto che fare semplicemente clic sul pulsante meno.
Venu Murthy,

2
helpLa funzione mostra solo ciò che dice il docstring. Hai mai provato se funziona con la definizione della funzione nella domanda?
0xc0de,

@ 0xc0de - L'hai provato? Perché funziona davvero. help()sputa molto di più della semplice docstring - anche su codice non documentato stampa comunque l'argspec e ti dice dove è stato definito il codice. La persona che ha pubblicato la domanda originale non ha chiarito se avesse bisogno di una risposta che fosse amichevole o umana. Se deve solo essere amico dell'uomo, help()è perfettamente adeguato.
ArtOfWarfare il

@ArtOfWarfare per niente, dato che ora dovresti analizzare qualsiasi cosa help()ritorni, e provare a trovare il argse kwargs.
Vallentin,

5

Buone notizie per le persone che vogliono farlo in modo portatile tra Python 2 e Python 3.6+: usare il inspect.getfullargspec()metodo. Funziona in Python 2.xe 3.6+

Come hanno sottolineato Jim Fasarakis Hilliard e altri, era in questo modo:
1. In Python 2.x: usa inspect.getargspec()
2. In Python 3.x: usa la firma, come getargspec()ed getfullargspec()era deprecato.

Tuttavia, a partire da Python 3.6 (a grande richiesta?), Le cose sono migliorate:

Dalla pagina della documentazione di Python 3 :

inspect.getfullargspec (func)

Modificato nella versione 3.6 : questo metodo era stato precedentemente documentato come deprecato a favore di signature()Python 3.5, ma tale decisione è stata annullata al fine di ripristinare un'interfaccia standard chiaramente supportata per il codice Python 2/3 single-source che migra getargspec()dall'API legacy .


3

inspect.getargspec () per soddisfare le tue esigenze

from inspect import getargspec

def func(a, b):
    pass
print len(getargspec(func).args)

1
Benvenuto in Stack Overflow! Per favore, non rispondere solo con il codice sorgente. Prova a fornire una bella descrizione del funzionamento della tua soluzione. Vedi: Come posso scrivere una buona risposta? . Grazie
sɐunıɔ ןɐ qɐp

2

Come suggeriscono altre risposte, getargspecfunziona bene finché la cosa da interrogare è in realtà una funzione. Non funziona per built-in funzioni quali open, len, ecc, e sarà un'eccezione in questi casi:

TypeError: <built-in function open> is not a Python function

La funzione di seguito (ispirata a questa risposta ) mostra una soluzione alternativa. Restituisce il numero di argomenti previsti da f:

from inspect import isfunction, getargspec
def num_args(f):
  if isfunction(f):
    return len(getargspec(f).args)
  else:
    spec = f.__doc__.split('\n')[0]
    args = spec[spec.find('(')+1:spec.find(')')]
    return args.count(',')+1 if args else 0

L'idea è di analizzare la specifica della funzione dalla __doc__stringa. Ovviamente questo si basa sul formato di detta stringa, quindi non è certo robusto!


2

func.__code__.co_argcountti dà il numero di tutti gli argomenti PRIMA *args

func.__kwdefaults__ti dà una spiegazione degli argomenti parola chiave DOPO *args

func.__code__.co_kwonlyargcount è uguale a len(func.__kwdefaults__)

func.__defaults__ti dà i valori degli argomenti opzionali che appaiono prima *args

Ecco la semplice illustrazione:

l'illustrazione

>>> def a(b, c, d, e, f=1, g=3, h=None, *i, j=2, k=3, **L):
    pass

>>> a.__code__.co_argcount
7
>>> a.__defaults__
(1, 3, None)
>>> len(a.__defaults__)
3
>>> 
>>> 
>>> a.__kwdefaults__
{'j': 2, 'k': 3}
>>> len(a.__kwdefaults__)
2
>>> a.__code__.co_kwonlyargcount
2

0

Nel:

import inspect 

class X:
    def xyz(self, a, b, c): 
        return 

print(len(inspect.getfullargspec(X.xyz).args))

Su:

4


Nota: se xyz non fosse all'interno della classe X e non avesse "sé" e solo "a, b, c", avrebbe stampato 3.

Per python inferiore a 3.5, potresti voler sostituire inspect.getfullargspeccon inspect.getargspecil codice sopra.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.