मैं पायथन फ़ंक्शन के तर्कों की संख्या कैसे पा सकता हूं?


163

मैं पायथन फ़ंक्शन के तर्कों की संख्या कैसे पा सकता हूं? मुझे यह जानने की आवश्यकता है कि इसके कितने सामान्य तर्क हैं और कितने नामित तर्क हैं।

उदाहरण:

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

इस विधि में 2 तर्क और 1 नामित तर्क हैं।


43
सवाल पूरी तरह से वारंट है; यदि यह नहीं था (चूंकि आप हमेशा स्रोत पढ़ सकते हैं), तो inspectमानक पुस्तकालय मॉड्यूल के लिए कोई औचित्य नहीं होगा ।
प्रवाह

बहुत सारी भाषाएँ कम से कम एक अनुचित सुविधा को लागू करती हैं। inspectतो यह कहना है कि पूरे मॉड्यूल अगर यह में एक विशेष समारोह था अनुचित किया जाएगा अनुचित है मॉड्यूल, अन्य सुविधाओं के एक बहुत कुछ है। इसके अलावा, यह देखना आसान है कि इस सुविधा का खराब उपयोग कैसे किया जा सकता है। (देखें stackoverflow.com/questions/741950 )। उस ने कहा, यह एक उपयोगी विशेषता है, विशेष रूप से सज्जाकार और अन्य कार्यों को लिखने के लिए जो फ़ंक्शन पर काम करते हैं।
user1612868

जवाबों:


131

पहले स्वीकार किए गए उत्तर के रूप में पदावनत किया गया है Python 3.0। उपयोग करने के बजाय inspect.getargspecअब आपको उस Signatureवर्ग के लिए विकल्प चुनना चाहिए जिसने इसे उलट दिया है।

समारोह के लिए एक हस्ताक्षर बनाना आसान है signatureसमारोह :

from inspect import signature

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

sig = signature(someMethod)

अब, आप या तो इसके मापदंडों को शीघ्रता से देख सकते strहैं:

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

या आप पैरामीटर ऑब्जेक्ट के माध्यम से विशेषता नामों का मानचित्रण भी प्राप्त कर सकते हैं sig.parameters

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

साथ ही, आप कॉल कर सकते हैं lenपर sig.parametersयह भी तर्क इस समारोह की आवश्यकता की संख्या को देखने के लिए:

print(len(params))  # 3

paramsमैपिंग में प्रत्येक प्रविष्टि वास्तव में एक ऐसी Parameterवस्तु है, जिसमें आपके जीवन को आसान बनाने के लिए और अधिक विशेषताएं हैं। उदाहरण के लिए, एक पैरामीटर को हथियाने और इसके डिफ़ॉल्ट मान को देखने के साथ अब आसानी से किया जाता है:

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

इसी तरह बाकी वस्तुओं के लिए parameters


पायथन 2.xउपयोगकर्ताओं के लिए, जबकि पदावनत inspect.getargspec नहीं किया जाता है, जल्द ही भाषा :-) होगी। Signatureवर्ग में उपलब्ध नहीं है 2.xश्रृंखला और नहीं होगा। इसलिए आपको अभी भी साथ काम करने की आवश्यकता है inspect.getargspec

अजगर 2 और 3 के बीच में परिवर्तित करने की है, यदि आप कोड है कि इंटरफेस पर निर्भर करता है getargspecअजगर 2 में और का उपयोग करने जा signatureमें 3भी मुश्किल है, आप मूल्यवान विकल्प क्या है का उपयोग करने का inspect.getfullargspec। यह getargspecफ़ंक्शन के तर्कों को पकड़ने के लिए एक समान इंटरफ़ेस प्रदान करता है (कुछ कॉल करने योग्य तर्क) जो कुछ अतिरिक्त मामलों को संभालने के दौरान भी getargspecऐसा नहीं करता है:

from inspect import getfullargspec

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

args = getfullargspec(someMethod)

जैसे getargspec, तर्कों का getfullargspecरिटर्न NamedTupleहोता है।

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

1
आपका स्वागत है @ GeorgSchölly। मुझे यह एक लोकप्रिय प्रश्न आश्चर्यचकित कर रहा था, जैसे यह समाधान प्रस्तुत किया गया था, जो या तो co_argcount
कमज़ोर

1
getfullargspecपायथन 2.x में लागू नहीं किया गया है, आपको उपयोग करने की आवश्यकता हैgetargspec
पीटर गिब्सन

getargspecपर बिल्ट-इन कार्य नहीं काम करता है: getargspec(open)देता TypeError: <built-in function open> is not a Python functionदेखें इस सवाल का जवाब कुछ विचार के लिए ...
starfry

अपने अंतिम उदाहरण में, जब आप करते print(args)हैं तो आपको नहीं defaults=(None,)मिलता है defaults=None
Seanny123

सी एक समारोह के लिए मूल पैरामीटर गणना प्राप्त करने का एक तरीका है जिसे सजावट के बाद सजाया गया है ..?
गुलाल

117
import inspect
inspect.getargspec(someMethod)

निरीक्षण मॉड्यूल देखें


5
आम तौर पर आप क्या चाहते हैं, लेकिन यह अंतर्निहित कार्यों के लिए काम नहीं करता है। बिल्डिंस के लिए इस जानकारी को प्राप्त करने का एकमात्र तरीका उनके डॉक स्ट्रिंग को पार्स करना है , जो कि बहुत ही सरल और उल्लेखनीय है।
सेरिन

5
यह पायथन 3 में वर्गीकृत है
noisecapella

क्या कोई समाधान है जो पायथन 3 में पदावनत नहीं है?
hlin117

1
यदि आप उस लिंक का अनुसरण करते हैं जो आप देखेंगे कि यह प्रयोग करने की अनुशंसा करता है inspect.signature- docs.python.org/3/library/inspect.html#inspect.signature
coderforlife

मैंने यहां डॉकस्ट्रिंग को पार्स किए बिना बिलिन फ़ंक्शन के लिए एक और संभावित दृष्टिकोण पोस्ट किया है: stackoverflow.com/questions/48567935/…
HelloWorld

31
someMethod.func_code.co_argcount

या, यदि वर्तमान फ़ंक्शन नाम अनिर्धारित है:

import sys

sys._getframe().func_code.co_argcount

4
@ हेलीज़, बस करो: dir(someMethod)-> 'func_code'; आगे बढ़ो: dir(someMethod.func_code)-> 'co_argcount'; आप dir()किसी ऑब्जेक्ट के उपलब्ध तरीकों को निर्धारित करने के लिए अंतर्निहित का उपयोग कर सकते हैं ।

@ खैर मैं भी कुरूप था, इसलिए मुझे यह docs.python.org/2/library/inspect.html#types-and-members
rodripf

अजगर 3 का समर्थन करने के लिए:six.get_function_code(someMethod).co_argcount
noisecapella

8
@noisecapella को किसी तीसरे पक्ष के मॉड्यूल की आवश्यकता नहीं है, जब आप बस कर सकते हैंsome_method.__code__.co_argcount
vallentin

1
सामान्य तौर पर, आपको इन चीजों को देखने के लिए फ़ंक्शन ऑब्जेक्ट के अंदर झांकना नहीं चाहिए। co_argcountकोड ऑब्जेक्ट के मूल्यांकन के दौरान आंतरिक रूप से उपयोग किया जाता है। मैं जो कहना चाह रहा हूं, वास्तव में इसकी कोई गारंटी नहीं है कि ये विशेषताएँ एक रिलीज़ से दूसरे में नहीं बदलेंगी।
दिमित्री फासरकिस हिलियार

16

inspect.getargspec ()

किसी फ़ंक्शन के तर्कों के नाम और डिफ़ॉल्ट मान प्राप्त करें। चार चीजों का एक टपल वापस किया जाता है: (आर्ग्स, वेरगेज, वार्क, डिफॉल्ट्स)। आर्ग्स तर्क नामों की एक सूची है (इसमें नेस्टेड सूची हो सकती है)। varargs और varkw * और ** तर्कों या कोई नहीं के नाम हैं। चूक डिफ़ॉल्ट तर्क मानों का एक समूह है या यदि कोई डिफ़ॉल्ट तर्क नहीं हैं; यदि इस टपल में n तत्व हैं, तो वे args में सूचीबद्ध अंतिम n तत्वों के अनुरूप हैं।

2.6 संस्करण में बदल गया: एक नाम दिया गया टपल ArgSpec (args, varargs, keywords, चूक)।

देखें कर सकते हैं-यू-सूची-कीवर्ड-तर्क-ए-अजगर-समारोह-प्राप्त करता है


5

ऊपर जोड़ते हुए, मैंने यह भी देखा है कि अधिकांश बार मदद () फ़ंक्शन वास्तव में मदद करता है

उदाहरण के लिए, यह उन तर्कों के बारे में सभी विवरण देता है जो इसे लेता है।

help(<method>)

नीचे देता है

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

लोगों के लिए यह अच्छा होगा कि वे किसी पोस्ट के बारे में टिप्पणी छोड़ दें, जो केवल माइनस बटन पर क्लिक करने की तुलना में गलत है।
वेणु मूर्ति

2
helpफ़ंक्शन केवल दिखाता है कि डॉकस्ट्रिंग क्या कहता है। यदि आपने प्रश्न में फ़ंक्शन परिभाषा के साथ काम किया है, तो क्या आपने परीक्षण किया है?
0xc0de

@ 0xc0de - क्या आपने इसका परीक्षण किया है? क्योंकि यह वास्तव में काम करता है। help()केवल डॉकस्ट्रिंग से अधिक बाहर थूकता है - यहां तक ​​कि अनजाने कोड पर भी यह argspec को प्रिंट करता है और आपको बताता है कि कोड कहां परिभाषित किया गया था। जिस व्यक्ति ने मूल प्रश्न पोस्ट किया था, वह स्पष्ट नहीं था कि क्या उन्हें मशीन या मानव के अनुकूल उत्तर की आवश्यकता थी। यदि इसे केवल मानव के अनुकूल होने की आवश्यकता है, help()तो पूरी तरह से पर्याप्त है।
आर्टऑफवर्फ

@ArtOfWarfare नहीं सब पर, के रूप में अब आप जो कुछ भी पार्स करने के लिए होता help()रिटर्न, और कोशिश करते हैं और पाते हैं argsऔर kwargs
vallentin

5

उन लोगों के लिए अच्छी खबर है जो पायथन 2 और पायथन 3.6+: उपयोग inspect.getfullargspec()विधि के बीच पोर्टेबल तरीके से ऐसा करना चाहते हैं । यह पायथन 2.x और 3.6+ दोनों में काम करता है

जैसा कि जिम फासाराकिस हिलियार्ड और अन्य ने बताया है, यह इस तरह से हुआ करता था:
1. पायथन 2.x में: उपयोग inspect.getargspec()
2. पायथन में 3.x: हस्ताक्षर का उपयोग करें, के रूप में getargspec()और getfullargspec()पदावनत किया गया।

हालाँकि, Python 3.6 को शुरू करना (लोकप्रिय मांग के द्वारा?), चीजें बेहतर की ओर बदल गई हैं:

पायथन 3 प्रलेखन पृष्ठ से :

inspect.getfullargspec (समारोह)

संस्करण 3.6 में परिवर्तित : इस विधि को पहले signature()पायथन 3.5 के पक्ष में पदावनत के रूप में प्रलेखित किया गया था , लेकिन यह निर्णय एकल-स्रोत पायथन 2/3 कोड के लिए स्पष्ट रूप से समर्थित मानक इंटरफ़ेस को पुनर्स्थापित करने के लिए उलट दिया गया है जो विरासत getargspec()एपीआई से दूर पलायन कर रहा है ।


3

अपनी आवश्यकताओं को पूरा करने के लिए inspect.getargspec ()

from inspect import getargspec

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

1
ढेर अतिप्रवाह में आपका स्वागत है! कृपया स्रोत कोड के साथ जवाब न दें। आपका समाधान कैसे काम करता है, इसके बारे में एक अच्छा विवरण प्रदान करने का प्रयास करें। देखें: मैं एक अच्छा जवाब कैसे लिखूं? । धन्यवाद
sɐunıɔ ןɐ qɐp

2

जब तक अन्य उत्तर सुझाते हैं, getargspecतब तक अच्छी तरह से काम करता है जब तक कि बात की जा रही है वास्तव में एक फ़ंक्शन है। यह के लिए काम नहीं करता है में निर्मित इस तरह के रूप में कार्य करता open, len, आदि, और इस तरह के मामलों में एक अपवाद फेंक देगा:

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

निम्न फ़ंक्शन ( इस उत्तर से प्रेरित ) एक वर्कअराउंड प्रदर्शित करता है। इसके द्वारा अपेक्षित args की संख्या लौटाता है 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

__doc__स्ट्रिंग से फ़ंक्शन स्पेक को पार्स करने का विचार है । जाहिर है कि यह उक्त स्ट्रिंग के प्रारूप पर निर्भर करता है इसलिए शायद ही मजबूत हो!


2

func.__code__.co_argcountआपको किसी भी तर्क से पहले की संख्या देता है *args

func.__kwdefaults__आपको AFTER के तर्कों की एक तानाशाही देता है *args

func.__code__.co_kwonlyargcount के बराबर है len(func.__kwdefaults__)

func.__defaults__आपको पहले सामने आने वाले वैकल्पिक तर्कों के मान देता है *args

यहाँ सरल चित्रण है:

चित्रण

>>> 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

में:

import inspect 

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

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

बाहर:

4


नोट: यदि xyz कक्षा X के अंदर नहीं था और उसके पास "स्वयं" नहीं था और सिर्फ "a, b, c" था, तो यह 3 मुद्रित होता।

3.5 नीचे अजगर के लिए, आप को बदलने के लिए चाहते हो सकता है inspect.getfullargspecद्वारा inspect.getargspecउपरोक्त कोड में।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.