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)dà 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.