個人的なPythonメモです。
環境
$ python Python 3.6.0 |Anaconda custom (x86_64)| (default, Dec 23 2016, 13:19:00) [GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>>
アスタリクスのみの引数
書籍「Effective Python」読んでたら、以下のような関数がありました。
def func(x, y, *, z=100): print(x, y, z)
なんか、引数の真ん中に変なのいる
このように引数に アスタリクス (*) のみを記載すると、これ以降では、キーワード引数を指定する際に
キーワードの指定を強制できるとのこと。
通常
def with_keyword_params(x, y, z=100, zz=200): print(x, y, z, zz)
ってクソ関数があった場合に
with_keyword_params(10, 20, 30, 40)
って指定も出来るし
with_keyword_params(10, 20, 30, zz=333)
って指定もできます。
でも、アスタリクスだけの引数を追加した関数
def with_keyword_params2(x, y, *, z=100, zz=200): print(x, y, z, zz)
だと
with_keyword_params2(10, 20, 30, 40)
ってやるとエラーになります。 キーワード引数部分を指定する際は必ず
with_keyword_params(10, 20, z=11, zz=22)
ってやらないと駄目に出来る。
サンプル
以下サンプルです。
# coding: utf-8 """ 関数についてのサンプルです。 """ from trypython.common.commoncls import SampleBase from trypython.common.commonfunc import hr, pr class Sample(SampleBase): def exec(self): # ----------------------------------------- # 最も基本的な関数の形 # ----------------------------------------- func = Sample.normal_func hr(func.__name__) pr(func.__name__, func(10, 20)) # ----------------------------------------- # 可変引数あり # 可変引数は、慣習的に *args と記述する # ----------------------------------------- func = Sample.with_args hr(func.__name__) pr(func.__name__, func(10, 20, 30, 40, 50)) # ----------------------------------------- # デフォルト値あり # ----------------------------------------- func = Sample.with_default_value hr(func.__name__) pr(func.__name__, func(10, 20)) # ----------------------------------------- # キーワード引数あり # キーワード引数は、慣習的に **kwargs と記述する # ----------------------------------------- func = Sample.with_kwargs hr(func.__name__) pr(func.__name__, func(10, 20, z=100, zz=200)) # ----------------------------------------- # 特殊な アスタリクスのみ引数 を持つ関数 # ----------------------------------- # 引数リストの中に「*」のみの引数を定義すると # それ以降の引数について強制的にキーワード指定 # をして呼び出すように出来る。 # # 通常 func(x, y, z=100) のように定義して # いると、 func(10, 20, z=111) のように # 呼ぶことも出来るし、 func(10, 20, 111) と # 呼ぶことも出来る。 # # だが、func(x, y, *, z=100) と定義した場合 # func(10, 20, 111)と呼ぶとエラーとなり # func(10, 20) か func(10, 20, z=111) と # いうようにキーワード引数を明示的に指定しないと # 受け付けないように出来る。 # ----------------------------------------- func = Sample.with_asterisk_sentinel hr(func.__name__ + '(sentinel)') pr(func.__name__, func(10, 20)) pr(func.__name__, func(10, 20, z=500)) try: pr(func.__name__, func(10, 20, 300)) except TypeError as err: pr('with_asterisk_sentinel', err) @staticmethod def normal_func(x, y): return x + y @staticmethod def with_args(x, y, *args): return sum((x, y, *args)) @staticmethod def with_default_value(x, y, z=100): return x + y + z @staticmethod def with_kwargs(x, y, **kwargs): return sum((x, y, *(kwargs.values()))) @staticmethod def with_asterisk_sentinel(x, y, *, z=100, zz=200): return x + y + z + zz def go(): obj = Sample() obj.exec() if __name__ == '__main__': go()
結果
以下のようになります。
----------------normal_func---------------- normal_func=30 ----------------with_args---------------- with_args=150 ----------------with_default_value---------------- with_default_value=130 ----------------with_kwargs---------------- with_kwargs=330 ----------------with_asterisk_sentinel(sentinel)---------------- with_asterisk_sentinel=330 with_asterisk_sentinel=730 with_asterisk_sentinel=TypeError('with_asterisk_sentinel() takes 2 positional arguments but 3 were given',)
ソース
以下の場所でも見れます。
疑問
このアスタリクス(*)だけの引数、Python界隈では正式にはなんて用語で呼ぶのでしょうか???
8. 複合文 (compound statement) — Python 3.6.1 ドキュメント
ここみても、特に明記してあるようには見えなかったのです。
2017-05-04 ちゃんとPEPとして発行されているのを発見。
PEP 3102 – Keyword-Only Arguments www.python.org
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場