質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

4回答

2433閲覧

Pythonを例に デフォルト引数の上手な使い方

_Victorique__

総合スコア1392

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/10/08 08:23

編集2018/10/08 08:56

デフォルト引数を使っているときに、呼び出しがネストしすぎると逆にデフォルト引数が鬱陶しくなったり、
内部で引数の指定し忘れが起こったりしそうになります。
Pythonの場合で例をあげます。

python

1class TestA: 2 def __init__(self, num): 3 self._num = num 4 5 def calc_testA(self, n=1): 6 return self._num * self._private_calc(n=n) # この部分(n=n)が冗長かつミスが起こりやすい 7 8 def _private_calc(self, n=1): # つまりはここのデフォルト引数を普通の引数に直す 9 return 100*n 10 11class TestB: 12 def __init__(self, num): 13 self._num = num 14 15 def calc_testB(self, num_a, n=1): 16 test_a = TestA(num_a) 17 return test_a.calc_testA(n=3)*self._num 18 19def main() 20 test_b = TestB(7) 21 res = test_b.calc_testB(4, n=20)

このように関数が2個ネストするような場合にデフォルト引数を連続させてしまうのは悪いと考えているのですが
そういう認識で合っていますでしょうか?また、むしろデフォルト引数でも良いという考え方があるならば教えて欲しいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tiitoi

2018/10/08 08:28 編集

関数定義でデフォルトの値を設定するのは「デフォルト引数」といい、キーワード引数は関数を呼び出す際の指定方法の1つですが、それを混同されていませんか?
_Victorique__

2018/10/08 08:55

まさにその通りです!修正します!
guest

回答4

0

ベストアンサー

事前に確認しておきますが、
『デフォルト値の有無』と『キーワード引数の強制』は関係ないです。

Python

1>>> def func(a=0): pass 2... 3>>> func(1) 4>>> func(a=1) 5>>>

Python

1>>> def func(*, a): pass 2... 3>>> func(1) 4Traceback (most recent call last): 5 File "<stdin>", line 1, in <module> 6TypeError: func() takes 0 positional arguments but 1 was given 7>>> func(a=1) 8>>>

Python

1>>> def func(*, a=0): pass 2... 3>>> func(1) 4Traceback (most recent call last): 5 File "<stdin>", line 1, in <module> 6TypeError: func() takes 0 positional arguments but 1 was given 7>>> func(a=1) 8>>>

####キーワード引数が鬱陶しい件
実引数の命名が適切ならば、位置引数として取り渡せば良いかと。

####デフォルト値が鬱陶しい件
それぞれの関数/メソッドについて、デフォルト値の採択が適当か再検討すべきでしょう。
具体的な状況に依ります。

投稿2018/10/08 08:35

編集2018/10/08 08:56
LouiS0616

総合スコア35660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

_Victorique__

2018/10/08 09:05

回答有難う御座います。 def func(*, a): pass これに対して func(*[1], 1) でエラーが出る理由が分かりません。このアスタリスクはどのように解釈すれば良いですか?
LouiS0616

2018/10/08 09:07

関数のパラメータリストに単に * がある場合、それ以降の引数をキーワード付きで引き渡すことを強制できます。 アンパックの * とは関係ないです。
_Victorique__

2018/10/08 09:23 編集

はーなるほどです。 つまりは def func(*, a=1):pass の場合は func() とすることもできるんですね! 勉強になりました!有り難うございます!
guest

0

鬱陶しければデフォルト値を使わないのはありだと思いますが、

n=nのような記述は(冗長とはいえ)意図するところがわかりやすく、これをやめるとかえってミスりそうなので、キーワード引数にはしておいた方が個人的には好みです。

投稿2018/10/08 12:16

hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

関数を2つ作ったほうが明確になる気がします。

class TestA: def __init__(self, num): self._num = num def calc_testA(self, n=1): return self._num * self._private_calc(n) def _private_calc(self, n): return 100*n def _private_calc_default(self): # ところでこれを呼び出すサンプルケースがそもそもないのだが… return self._private_calc(1)

投稿2018/10/08 09:12

mather

総合スコア6753

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

self._num * self._private_calc(n=n) # この部分(n=n)が冗長かつミスが起こりやすい

引数名の命名が不適切なだけではないでしょうか?

後は、LouiS0616さんの書かれたように、 ディフォルト値の採択が適切かどうか。

投稿2018/10/08 09:04

pepperleaf

総合スコア6383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

_Victorique__

2018/10/08 09:12

確かに命名が不適切かもしれませんが、これは単純な例です。 デフォルト引数で次から次に渡していく過程が無駄?なように思えたのでこういう質問になりました。 結局はユーザーがいじれる(publicな)部分だけデフォルト引数にしてしまっても良いのではないか?という疑問が生じました。内部でもデフォルト引数で扱う必要性はあるでしょうか?位置引数で取り扱っても良いのではないでしょうか?もちろん引数名が適切であるのが大前提ですが。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問