2010-04-20 7 views
69

फ़ंक्शन ऑब्जेक्ट को देखते हुए, मैं इसका हस्ताक्षर कैसे प्राप्त कर सकता हूं? उदाहरण के लिए,मैं डिफ़ॉल्ट तर्क मान सहित फ़ंक्शन के हस्ताक्षर को कैसे पढ़ सकता हूं?

def myMethod(firt, second, third='something'): 
    pass 

मैं "myMethod(firt, second, third='something')" प्राप्त करना चाहता हूं।

+3

क्या आप कृपया अपने विशिष्ट प्रश्न पर विस्तृत जानकारी दे सकते हैं और शायद अपेक्षित परिणाम के साथ एक उदाहरण दे सकते हैं? – jhwist

+0

संभवतः वह पाइथन या तृतीय-पक्ष पुस्तकालयों में कार्यक्षमता की तलाश में है जो विधि के नाम के अनुसार एक विधि के हस्ताक्षर (नाम और पैरामीटर के प्रकार और वापसी मूल्य) वापस कर देगा। –

+1

हस्ताक्षर कैसे करें इसे कैसे कॉल करें और ऐसा? 'सहायता (yourmethod) ' उदा। 'मदद (मानचित्र)' –

उत्तर

108
import inspect 

def foo(a, b, x='blah'): 
    pass 

print(inspect.getargspec(foo)) 
# ArgSpec(args=['a', 'b', 'x'], varargs=None, keywords=None, defaults=('blah',)) 

हालांकि, ध्यान दें कि inspect.getargspec() अजगर 3.0 के बाद से मान्य नहीं है।

पायथन 3.0--3.4 inspect.getfullargspec() की सिफारिश करता है।

पायथन 3.5+ inspect.signature() की सिफारिश करता है।

+0

विशेषताएँ त्रुटि: 'मॉड्यूल' ऑब्जेक्ट में कोई विशेषता नहीं है 'getargspec' –

+3

@ एसपीआई, आप एक मॉड्यूल पर 'inspect.getargspec' को कॉल कर रहे हैं, फ़ंक्शन नहीं। –

+0

धन्यवाद, समस्या ग्रहण के साथ थी जिसने निरीक्षण मॉड्यूल –

7

किसी ऑब्जेक्ट पर इसके बारे में जानने के लिए help पर कॉल करने का प्रयास करें।

>>> foo = [1, 2, 3] 
>>> help(foo.append) 
Help on built-in function append: 

append(...) 
    L.append(object) -- append object to end 
12
#! /usr/bin/env python 

import inspect 
from collections import namedtuple 

DefaultArgSpec = namedtuple('DefaultArgSpec', 'has_default default_value') 

def _get_default_arg(args, defaults, arg_index): 
    """ Method that determines if an argument has default value or not, 
    and if yes what is the default value for the argument 

    :param args: array of arguments, eg: ['first_arg', 'second_arg', 'third_arg'] 
    :param defaults: array of default values, eg: (42, 'something') 
    :param arg_index: index of the argument in the argument array for which, 
    this function checks if a default value exists or not. And if default value 
    exists it would return the default value. Example argument: 1 
    :return: Tuple of whether there is a default or not, and if yes the default 
    value, eg: for index 2 i.e. for "second_arg" this function returns (True, 42) 
    """ 
    if not defaults: 
     return DefaultArgSpec(False, None) 

    args_with_no_defaults = len(args) - len(defaults) 

    if arg_index < args_with_no_defaults: 
     return DefaultArgSpec(False, None) 
    else: 
     value = defaults[arg_index - args_with_no_defaults] 
     if (type(value) is str): 
      value = '"%s"' % value 
     return DefaultArgSpec(True, value) 

def get_method_sig(method): 
    """ Given a function, it returns a string that pretty much looks how the 
    function signature would be written in python. 

    :param method: a python method 
    :return: A string similar describing the pythong method signature. 
    eg: "my_method(first_argArg, second_arg=42, third_arg='something')" 
    """ 

    # The return value of ArgSpec is a bit weird, as the list of arguments and 
    # list of defaults are returned in separate array. 
    # eg: ArgSpec(args=['first_arg', 'second_arg', 'third_arg'], 
    # varargs=None, keywords=None, defaults=(42, 'something')) 
    argspec = inspect.getargspec(method) 
    arg_index=0 
    args = [] 

    # Use the args and defaults array returned by argspec and find out 
    # which arguments has default 
    for arg in argspec.args: 
     default_arg = _get_default_arg(argspec.args, argspec.defaults, arg_index) 
     if default_arg.has_default: 
      args.append("%s=%s" % (arg, default_arg.default_value)) 
     else: 
      args.append(arg) 
     arg_index += 1 
    return "%s(%s)" % (method.__name__, ", ".join(args)) 


if __name__ == '__main__': 
    def my_method(first_arg, second_arg=42, third_arg='something'): 
     pass 

    print get_method_sig(my_method) 
    # my_method(first_argArg, second_arg=42, third_arg="something") 
+0

इस बारे में कोई स्पष्टीकरण क्या है कि यह क्या करना है? – grantmcconnaughey

+0

कोड नमूना में टिप्पणी पोस्ट की गई, उम्मीद है कि मदद करता है। –

+0

सुंदर, धन्यवाद! – grantmcconnaughey

21
यकीनन

एक समारोह के लिए हस्ताक्षर help(function) होगा खोजने के लिए सबसे आसान तरीका है:

>>> def function(arg1, arg2="foo", *args, **kwargs): pass 
>>> help(function) 
Help on function function in module __main__: 

function(arg1, arg2='foo', *args, **kwargs) 
इसके अलावा

, अजगर 3 में एक विधि inspect मॉड्यूल signature कहा जाता है, जो प्रतिनिधित्व करने के लिए बनाया गया है के लिए जोड़ा गया signature of a callable object and its return annotation:

>>> from inspect import signature 
>>> def foo(a, *, b:int, **kwargs): 
...  pass 

>>> sig = signature(foo) 

>>> str(sig) 
'(a, *, b:int, **kwargs)' 

>>> str(sig.parameters['b']) 
'b:int' 

>>> sig.parameters['b'].annotation 
<class 'int'> 
+1

परफेक्ट के साथ बुलाए गए' def foo (a, *, b: int, ** kwargs) 'के साथ काम करने के लिए इसे समायोजित कर सकते हैं तो बेहतर होगा। मैं वास्तव में एक समारोह के लिए एक मानव पठनीय हस्ताक्षर बाहर डंप करना चाहता था। – ArtOfWarfare

+2

'inspect.signature'' funcsigs 'बैकपोर्ट प्रोजेक्ट के माध्यम से पाइथन 2 के लिए भी उपलब्ध है: https://pypi.python.org/pypi/funcsigs – ncoghlan

5

हो सकता है कि एक सा पार्टी के लिए देर हो चुकी है, लेकिन एक के आदेश रखने के लिए आप भी चाहते हैं rguments और उनके डिफ़ॉल्ट, तो आप Abstract Syntax Tree module (ast) का उपयोग कर सकते हैं।

यहाँ अवधारणा का एक सबूत (तर्क सॉर्ट और उनके डिफ़ॉल्ट उन्हें मैच के लिए कोड सावधान रहना निश्चित रूप से सुधार किया जा सकता/अधिक स्पष्ट कर दिया) है:

import ast 

for class_ in [c for c in module.body if isinstance(c, ast.ClassDef)]: 
    for method in [m for m in class_.body if isinstance(m, ast.FunctionDef)]: 
     args = [] 
     if method.args.args: 
      [args.append([a.col_offset, a.id]) for a in method.args.args] 
     if method.args.defaults: 
      [args.append([a.col_offset, '=' + a.id]) for a in method.args.defaults] 
     sorted_args = sorted(args) 
     for i, p in enumerate(sorted_args): 
      if p[1].startswith('='): 
       sorted_args[i-1][1] += p[1] 
     sorted_args = [k[1] for k in sorted_args if not k[1].startswith('=')] 

     if method.args.vararg: 
      sorted_args.append('*' + method.args.vararg) 
     if method.args.kwarg: 
      sorted_args.append('**' + method.args.kwarg) 

     signature = '(' + ', '.join(sorted_args) + ')' 

     print method.name + signature 
3

तो तुम सब करने की कोशिश कर रहे हैं प्रिंट है समारोह फिर pydoc का उपयोग करें।

import pydoc  

def foo(arg1, arg2, *args, **kwargs):                  
    '''Some foo fn'''                      
    pass                         

>>> print pydoc.render_doc(foo).splitlines()[2] 
foo(arg1, arg2, *args, **kwargs) 

यदि आप वास्तव में फ़ंक्शन हस्ताक्षर का विश्लेषण करने की कोशिश कर रहे हैं तो निरीक्षण मॉड्यूल के argspec का उपयोग करें। मुझे ऐसा करना था जब किसी उपयोगकर्ता के हुक स्क्रिप्ट फ़ंक्शन को सामान्य ढांचे में मान्य करते थे।

संबंधित मुद्दे