parameters 定義 - 関数が必要とするパラメータの量をプログラムで決定する-Python



呼び出し 一覧 (6)

この質問には既に回答があります:

私は単純なコマンドラインユーティリティを作成していたし、適切な機能にリンクしているキーワードを使って、ある種のcase文として辞書を使用していました。 関数はすべて異なる引数を必要とするので、ユーザーが各関数に必要な正しい量の引数を入力したかどうかを現在確認しています。 {Keyword:(FunctionName, AmountofArguments)}という形式で辞書のcase文の中に必要な量を入れました。

しかし、現在の設定は完全にうまく動作しますが、関数内で必要な引数の数を決定する方法があって、Googleの試行がこれまで何の価値も返されていないのであれば、自己改良のために不思議に思っていましたが、どのようにargsとkwargs彼らが許す無限の議論のために、そのようなコマンドをねじ込むことができます。


Answers

varargsとkwargsの使用のためにあなたが望むものは一般的に不可能ですが、 inspect.getargspec (Python 2.x)とinspect.getfullargspec (Python 3.x)は近づきます。

  • Python 2.x:

    >>> import inspect
    >>> def add(a, b=0):
    ...     return a + b
    ...
    >>> inspect.getargspec(add)
    (['a', 'b'], None, None, (0,))
    >>> len(inspect.getargspec(add)[0])
    2
    
  • Python 3.x:

    >>> import inspect
    >>> def add(a, b=0):
    ...     return a + b
    ...
    >>> inspect.getfullargspec(add)
    FullArgSpec(args=['a', 'b'], varargs=None, varkw=None, defaults=(0,), kwonlyargs=[], kwonlydefaults=None, annotations={})
    >>> len(inspect.getfullargspec(add).args)
    2
    

これはすでに答えられていますが、inspectモジュールがなければsomeMethod.func_code.co_argcount


inspect.getargspec()

関数の引数の名前とデフォルト値を取得します。 4つのものからなる組(args、varargs、varkw、defaults)が返されます。 argsは引数名のリストです(ネストされたリストを含んでいる可能性があります)。 varargsとvarkwは*引数と**引数の名前です。 defaultsはデフォルトの引数値のタプルです。デフォルトの引数がない場合はNoneです。 このタプルにn個の要素がある場合、それらはargsにリストされている最後のn個の要素に対応します。


Python 3ではsomeMethod.__code__.co_argcount使いsomeMethod.__code__.co_argcount

someMethod.func_code.co_argcountがもうsomeMethod.func_code.co_argcountしないため)


優れた質問。 私はちょうどコールバック引数を取る関数を書いたかったという問題がありました。 そのコールバックの引数の数に応じて、それを別々に呼び出す必要があります。

私はgimelの答えで始まり、 inspectモジュールとよく反応しない組み込み関数に対処できるように拡張しました( raise TypeError )。

関数がまさに1つの引数を必要とするかどうかを調べるコードは次のとおりです。

def func_has_one_arg_only(func, typical_argument=None, ignore_varargs=False):
    """True if given func expects only one argument

    Example (testbench):
    assert not func_has_one_arg_only(dict.__getitem__), 'builtin 2 args'
    assert func_has_one_arg_only(lambda k: k), 'lambda 1 arg'
    assert not func_has_one_arg_only(lambda k,x: k), 'lambda 2 args'
    assert not func_has_one_arg_only(lambda *a: k), 'lambda *a'
    assert not func_has_one_arg_only(lambda **a: k), 'lambda **a'
    assert not func_has_one_arg_only(lambda k,**a: k), 'lambda k,**a'
    assert not func_has_one_arg_only(lambda k,*a: k), 'lambda k,*a'

    assert func_has_one_arg_only(lambda k: k, ignore_varargs=True), 'lambda 1 arg'
    assert not func_has_one_arg_only(lambda k,x: k, ignore_varargs=True), 'lambda 2 args'
    assert not func_has_one_arg_only(lambda *a: k, ignore_varargs=True), 'lambda *a'
    assert not func_has_one_arg_only(lambda **a: k, ignore_varargs=True), 'lambda **a'
    assert func_has_one_arg_only(lambda k,**a: k, ignore_varargs=True), 'lambda k,**a'
    assert func_has_one_arg_only(lambda k,*a: k, ignore_varargs=True), 'lambda k,*a'
    """

    try:
        import inspect
        argspec = inspect.getargspec(func)
    except TypeError:                   # built-in c-code (e.g. dict.__getitem__)
        try:
            func(typical_argument)
        except TypeError:
            return False
        else:
            return True
    else:
        if not ignore_varargs:
            if argspec.varargs or argspec.keywords:
                return False
        if 1 == len(argspec.args):
            return True
        return False
    raise RuntimeError('This line should not be reached')

varargs引数*argsおよび**kwargs関連する動作は、 ignore_varargsパラメータで制御できます。

typical_argumentパラメータはkludgeです: inspectがうまく動作inspectない場合、例えば前述の組み込み関数の場合、関数を1つの引数で呼び出して何が起こるかを調べます。

このアプローチの問題は、 raise TypeErrorraise TypeError理由が複数あることです。誤った数の引数が使用されているか、間違った型の引数が使用されています。 ユーザーがtypical_argumentを提供できるようにすることで、私はこの問題を回避しようとしています。

これはいいことではありません。 しかし、それは同じ質問をしている人達に役立つかもしれませんし、検査がCコード化された関数の実装をinspectことができないという事実にもinspectます。 おそらく人々はより良​​い提案をしていますか?


ここに私の解決策があります。 これにより、任意のパラメータを残すことができます。 オプションのパラメータの順序は重要ではなく、カスタム検証を追加できます。

function YourFunction(optionalArguments) {
            //var scope = this;

            //set the defaults
            var _value1 = 'defaultValue1';
            var _value2 = 'defaultValue2';
            var _value3 = null;
            var _value4 = false;

            //check the optional arguments if they are set to override defaults...
            if (typeof optionalArguments !== 'undefined') {

                if (typeof optionalArguments.param1 !== 'undefined')
                    _value1 = optionalArguments.param1;

                if (typeof optionalArguments.param2 !== 'undefined')
                    _value2 = optionalArguments.param2;

                if (typeof optionalArguments.param3 !== 'undefined')
                    _value3 = optionalArguments.param3;

                if (typeof optionalArguments.param4 !== 'undefined')
                    //use custom parameter validation if needed, in this case for javascript boolean
                   _value4 = (optionalArguments.param4 === true || optionalArguments.param4 === 'true');
            }

            console.log('value summary of function call:');
            console.log('value1: ' + _value1);
            console.log('value2: ' + _value2);
            console.log('value3: ' + _value3);
            console.log('value4: ' + _value4);
            console.log('');
        }


        //call your function in any way you want. You can leave parameters. Order is not important. Here some examples:
        YourFunction({
            param1: 'yourGivenValue1',
            param2: 'yourGivenValue2',
            param3: 'yourGivenValue3',
            param4: true,
        });

        //order is not important
        YourFunction({
            param4: false,
            param1: 'yourGivenValue1',
            param2: 'yourGivenValue2',
        });

        //uses all default values
        YourFunction();

        //keeps value4 false, because not a valid value is given
        YourFunction({
            param4: 'not a valid bool'
        });




python parameters function