আমি কীভাবে ডিফল্ট আর্গুমেন্টের মান সহ কোনও ফাংশনের স্বাক্ষরটি পড়তে পারি?


129

কোনও ফাংশন অবজেক্ট দেওয়া হয়েছে, আমি কীভাবে এর স্বাক্ষর পেতে পারি? উদাহরণস্বরূপ, এর জন্য:

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

আমি পেতে চাই "myMethod(firt, second, third='something')"


3
আপনি কি দয়া করে আপনার নির্দিষ্ট প্রশ্নটি বিস্তারিতভাবে বর্ণনা করতে পারেন এবং প্রত্যাশিত ফলাফলের সাথে একটি উদাহরণ দিতে পারেন?
jhwist

সম্ভবত তিনি পাইথন বা তৃতীয় পক্ষের লাইব্রেরিতে কার্যকারিতা সন্ধান করছেন যা পদ্ধতির নাম অনুসারে কোনও পদ্ধতির স্বাক্ষর (নাম এবং প্যারামিটারের নাম এবং প্রত্যাবর্তনের মান) প্রদান করবে।
মাইকেল পেট্রোটা

1
এটিকে কীভাবে কল করা যায় তার মতো স্বাক্ষর? help(yourmethod)উদাহরণস্বরূপ চেষ্টা করুনhelp(map)
নিক টি

উত্তর:


187
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.4 সুপারিশ করে inspect.getfullargspec()

পাইথন 3.5+ সুপারিশ করে inspect.signature()


অ্যাট্রিবিউটআরার: 'মডিউল' অবজেক্টটির কোনও 'গেটগারস্পেক' নেই
স্পা

3
@ এসপিআই, আপনি inspect.getargspecকোনও ফাংশন নয়, মডিউলটিতে কল করছেন।
মাইক গ্রাহাম

ধন্যবাদ, সমস্যাটি ছিল
গ্রহগ্রহের সাথে

যদি কোনও ফাংশনে আর্গুমেন্ট টীকাগুলি বা কীওয়ার্ডটি কেবল আর্গুমেন্ট থাকে (= আপনি যদি পাইথন 3 ব্যবহার করেন) আপনাকে তার getfullargspecপরিবর্তে কল করতে হবে। ( ValueError: Function has keyword-only arguments or annotations, use getfullargspec() API which can support them)
Badp করুন

2
@darth_coder: ইন Python2, getargspecউত্থাপন TypeErrorযদি ইনপুট হিসেবে স্বীকৃত নয় পাইথন ফাংশন - যেমন, একটি ফাংশন পাইথন বাস্তবায়িত। সিপিথনে, Exception.__init__সি তে প্রয়োগ করা হয়, তাই TypeError। কল স্বাক্ষরটি বুঝতে আপনাকে উত্স কোডটি পরীক্ষা করতে হবে। পাইথন 3 এ, আলাদাভাবে getargspecপ্রয়োগ করা হয়, এবং সেখানে inspect.getargspec(Exception.__init__)একটি ArgSpecউদাহরণ পাওয়া যায়।
unutbu

44

যুক্তিযুক্তভাবে কোনও ফাংশনের স্বাক্ষর সন্ধান করার সবচেয়ে সহজ উপায় হ'ল 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, যা কলযোগ্য বস্তুর স্বাক্ষর এবং এর প্রত্যাবর্তনের টীকাকে উপস্থাপন করার জন্য ডিজাইন করা হয়েছে :

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

3
inspect.signaturefuncsigsব্যাকপোর্ট প্রকল্পের মাধ্যমে পাইথন 2 এর জন্যও উপলব্ধ : পিপিআইপিথন.আরপিপি
এনকোঘ্লান

14
#! /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")

এটি করার কথা বলে এ সম্পর্কে কোনও ব্যাখ্যা?
গ্র্যান্টমেকনৌঘে

1
কোড নমুনায় মন্তব্য যুক্ত হয়েছে, আশা করি এটি সহায়তা করে।
অরূপ মালাকার

সুন্দর জিনিস। আরও ভাল হবে যদি আপনি এটিকেdef foo(a, *, b:int, **kwargs)foo(4, b=3.3)
ofer. Sheffer

8

helpকোনও বিষয় সম্পর্কে এটির জন্য ফোন করার চেষ্টা করুন ।

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

append(...)
    L.append(object) -- append object to end

7

পার্টিতে কিছুটা দেরি হতে পারে তবে আপনি যদি যুক্তি এবং তাদের ডিফল্টের ক্রমটি রাখতে চান তবে আপনি বিমূর্ত সিনট্যাক্স ট্রি মডিউলটি ব্যবহার করতে পারেন (অ্যাস্ট)

এখানে ধারণার একটি প্রমাণ রয়েছে (আর্গুমেন্টগুলি সাজানোর জন্য কোডটি সাবধান করুন এবং তাদের ডিফল্টগুলির সাথে তাদের মেলে দেওয়ার বিষয়টি অবশ্যই উন্নত / আরও পরিষ্কার করা যেতে পারে):

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

নোট করুন যে অ-ডিফল্ট আর্গুমেন্টগুলি ডিফল্ট আর্গুমেন্টগুলি অনুসরণ করতে পারে না , তাই আমরা কেবল তাদের লেজ থেকে মিলিয়ে নিতে পারি?
এভেজেনি সার্জিভ

5

আপনি যা করার চেষ্টা করছেন তা যদি ফাংশনটি মুদ্রণ করে তবে পাইডোক ব্যবহার করুন।

import pydoc    

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

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

আপনি যদি ফাংশনের স্বাক্ষরটি বাস্তবে বিশ্লেষণ করার চেষ্টা করছেন তবে পরিদর্শন মডিউলটির আরগস্পেক ব্যবহার করুন। কোনও ব্যবহারকারীর হুক স্ক্রিপ্ট ফাংশনটিকে সাধারণ কাঠামোর সাথে বৈধতা দেওয়ার সময় আমাকে তা করতে হয়েছিল।


3

উদাহরণ কোড:

import inspect
from collections import OrderedDict


def get_signature(fn):
    params = inspect.signature(fn).parameters
    args = []
    kwargs = OrderedDict()
    for p in params.values():
        if p.default is p.empty:
            args.append(p.name)
        else:
            kwargs[p.name] = p.default
    return args, kwargs


def test_sig():
    def fn(a, b, c, d=3, e="abc"):
        pass

    assert get_signature(fn) == (
        ["a", "b", "c"], OrderedDict([("d", 3), ("e", "abc")])
    )

2

কমান্ড লাইনে% আইডিএফ ব্যবহার করুন (আইপিথন), এটি কেবল স্বাক্ষর মুদ্রণ করবে।

যেমন %pdef np.loadtxt

 np.loadtxt(fname, dtype=<class 'float'>, comments='#', delimiter=None, converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0, encoding='bytes')
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.