7

一部のブリチンもキーワード引数を受け入れないように、コードがキーワード引数を受け入れないようにしようとしていますが、それができません。ここに、私の限られた理解による私の考えがあります:-

def somefunc(a,b):
    print a,b

somefunc(10,20)

出力:

10 20

さて、次のように実行すると(これは関数定義でキーワード引数であるとは想定されていませんが、関数呼び出しを見ると、キーワード引数を受け入れる関数を呼び出す場合と同じ構文のようです) :

somefunc(b=10,a=20)

出力:

20 10

2つの質問があります:-

  1. 関数定義ではなく関数呼び出しを見るとsomefunc(b=10,a=20)、これは通常の引数のみを受け入れる関数またはキーワード引数を受け入れる関数のいずれかであるように見えます。通訳は2つをどのように区別しますか?
  2. 多くのビルトインのようにキーワード引数を受け入れないように、関数をフォームに変換することは可能ですか?

なぜ私はこれをしたいのですか? 私はこれができるかどうかをチェックしているだけなので、Pythonを深く理解する上で何も見逃すことはありません。Pythonがそれを許可するかどうかはわかりません。

4

5 に答える 5

8

これを行うには、任意の引数リストを使用できます。http://docs.python.org/tutorial/controlflow.html#arbitrary-argument-listsを参照してください

例えば:

def somefunc(*args):
    print args[0], args[1]

キーワードなしで呼び出す:

somefunc(10,20)

与える:

10 20

キーワードによる呼び出し:

somefunc(a=10,b=20)

エラーが発生します:

TypeError: someFunc() got an unexpected keyword argument 'a'

しかし、なぜこれをしたいかは不明です。

于 2012-09-08T18:57:18.513 に答える
5

ad 1)正しい名前は、のように呼び出された場合、Pythonによって自動的に検証されますsomefunct(name=value, ...)。パラメータの正確な標準順序を覚えておく必要はなく、パラメータのわかりやすい名前を持つ関数を覚えていれば、毎月ドキュメントを調べて「神経症的」すぎることを確認する必要があります。それらが受け入れられるかどうかがテストされます。 Pythonによる。それどころか、使用されたパラメータの正しい順序は、ドキュメントによってのみ確認できます。名前付きパラメーターによる呼び出しは、位置パラメーターの非常に長いリストよりも優先されます。したがって、報告された動作は十分に根拠があります。(もちろん、短い1文字のパラメーター「a、b」は間違いを防ぐのに役立ちません。)

ad 2)必要なパラメーターの固定数が少ないCで記述されたいくつかのよく知られた組み込みの高速関数は、名前付きパラメーターでの呼び出しをサポートしていません。(例hasattr

これは、単純なヘッダーのみを使用する...(... PyObject *args)ため、すべての名前付きパラメーターが自動的に拒否されるためです。(PythonはCソースの引数の名前をイントロスペクトすることはできません。:-)

他の多くのC関数にはヘッダーが...(... PyObject *args, PyObject *kwds)あり、はるかに複雑な検証PyArg_ParseTupleAndKeywordsを実装し、名前をドキュメント文字列に書き込むことで、名前の正確なリストを明示的にサポートします。


編集:Python 3.8では、新しい関数パラメーター構文によって位置のみのパラメーターが可能であり、一部の関数パラメーターを位置的に指定する必要があり、キーワード引数として使用できないことを示します。/

def somefunc(a, b, /):
    print(a, b)
于 2012-09-09T07:07:58.750 に答える
4

関数の定義ではなく、関数呼び出しsomefunc(b = 10、a = 20)を見ると、これは通常の引数のみを受け入れる関数の呼び出しか、キーワード引数を受け入れる関数のいずれかであるように見えます。通訳は2つをどのように区別しますか?

これがあなたが求めているものであるかどうかはわかりませんが、私があなたを正しく理解していれば、答えは「そうではない」です。関数で引数がどのように定義されていても、キーワードを使用して関数を呼び出すことができます。キーワード構文(たとえば)を使用して引数を渡すと、Pythonは対応する値を関数定義内の同じ名前の引数にバインドします。デフォルト値が定義されているかどうかは関係ありません。2種類の関数定義は、異なる「種類」の引数を作成しません。引数の一部にデフォルト値がある場合とない場合があるだけです。だから、あなたがするかどうかにかかわらず、あなたはまだすることができます。唯一の制限は、最初に位置引数を渡す/定義する必要があることです(たとえば、f(a=...)def f(a)def f(a=2)f(a=...)def f(a=2, b)またはf(a=2, 3))。この回答も参照してください。

あなたの質問の2番目の部分に関しては、Python関数が名前付き引数のキーワードで渡された値を受け入れるのを止める方法を私は知りません。その場合にのみ定義する*argsと、キーワード引数は受け入れられませんが、位置引数に個別の名前を付けることはできません。

于 2012-09-08T18:54:15.907 に答える
3

Pythonには、キーワード引数と位置引数の間にそれほど強い違いはありません。実際、それは次のように単純です。

位置引数は、関数呼び出しにリストされている順序で解析されます。 キーワード引数は任意の順序で追加できますが、位置引数の前に置くことはできません。

だから、あなたがこれを持っているなら:

def foo(x):
    pass

できるよ:

foo(1) # positional
foo(x=1) # keyword

foo()ただし、デフォルト値を指定しなかったため、実行できません。

同様に、これがある場合:

def foo(x,y='hello'):
    pass

foo(1) # this works fine
foo() # this is invalid, as an argument without a default isn't passed
foo(y='hello',1) # error - positional arguments come before keyword arguments

任意の引数リストを読むことを忘れないでください。

于 2012-09-08T18:58:32.053 に答える
0

これは非常に悪いPython機能であり、非常に保守不可能でバグのあるコードにつながる可能性があると思います。あなたが関数を持っていたとしましょう:

def myurl(x, y):
    url = "{}:{}".format(x, y)
    return url

位置をキーワード引数に置き換えることを有効にするのは良い考えのように見えるかもしれませんが、そうしないでください。この関数がキーワード引数で呼び出されるのを妨げるPythonオプションがないことに驚いています。

>> print myurl(x="localhost", y=8080)

誰かがライブラリを理解した場合、次のように書くと読みやすくなります。

def myurl(hostname, port):
    url = "{}:{}".format(hostname, port)
    return url

次に、キーワード呼び出しを使用した残りのコードmyurl(x="localhost", y=8080)は失敗します。

TypeError: myurl() got an unexpected keyword argument 'x'

これは、ローカル関数変数が突然グローバル変数になったことを意味します。この問題がPython3で何らかの形で解決されることを期待していました。

于 2012-10-29T22:06:04.357 に答える