2009-03-18 8 views
7

オリジナル質問Python:ブール値と文字列の両方を返しても問題ありませんか?

シリアルポートに特定の文字列が表示されるのを待っていて、文字列が見つかるまですべての文字を返します。そうでない場合はfalseを返します。これは非常に便利ですが、それが悪い練習とみなされるかどうかは疑問でしたか?

明確化:

第一の目標は、一定時間内に表示されるように特定文字列を待つことです。 IOエラーを除いて、可能な結果はTrue(文字列が表示された)またはFalseです。 2番目の目標は、実際の回答が検索される前に解析したい情報がある可能性があるためです。プライマリとセカンダリの目標を1つの戻り値で組み合わせることができると私は考えました。

def MyFunc(s, timeout) : 
    test = get_some_input(timeout) 
    if test.endswith(s) 
     return test 
    else 
     return False 

編集:もう一つの提案された答えは、例外を発生させることです。私はそれが良い考えだとは思わない。なぜならタイムアウトは期待された動作だからだ。つまり、タイムアウトを指定するパラメータがある場合、タイムアウトが可能な結果であり、例外ではありません。

編集2: 入力を保存する必要があるので、おそらくクラスを使用するのが適切な解決策です。関数の待機は明確な戻り値を持ちますが、タイムアウトまで読み込まれた文字列全体にもアクセスできます。

class Parser : 
     def __init__(self, sport_name): 
       self.currentMsg = '' 
       self.ser = serial.Serial(sport_name, 115200) 
     def WaitFor(self, s, timeOut=None): 
       self.ser.timeout = timeOut 
       self.currentMsg = '' 
       while self.currentMsg.endswith(s) != True : 
         # should add a try catch here 
         c=self.ser.read() 
         if c != '' : 
           self.currentMsg += c 
         else : 
           print 'timeout waiting for ' + s 
           return False 
       return True 

答えて

6

文字列またはブール値を返す代わりに、文字列とブール値(タイトルのように)を返す方がよいでしょう。戻り値が何を意味するのか把握する必要はありません。それは完全に明示的でなければならず、直交問題は異なる変数に分けられるべきです。

(okay,value) = get_some_input(blah); 
if (okay): print value 

私はそれが面白いと感じるので、タプルをたくさん返却しない傾向があります。しかし、そうすることは完全に有効です。

戻り値 "なし"は有効な解決策ですが、ここで既に説明しました。

+0

それは直角のものが完全に正しいです。だからタプルを返すことは良い解決策になるでしょうが、私はこれにはまだとても慣れていないし、クラスを使ってシリアルポートを埋め込むことができ、さらに拡張することができます。 – shodanex

+0

だから、もしokayがFalseならば、値はどうあるべきですか? – SilentGhost

+0

@SilentGhost:値は、これまでの入力読み取り値です(文字列が見つかるか、タイムアウトが発生するまで)。 – jfs

25

None代わりのFalseを戻すために、より適していると思いませんか?

+0

はい、どれも適切ではありません –

+0

しかし、他の回答に記載されているように、例外はもっとPythonです。 –

+0

この場合、例外はPythonicではありません。標準ライブラリ、特にselect.selectとre.matchの動作を見てください。 –

5

便利なことは、この場合は空の文字列を返すことです。

さらに、Pythonの空の文字列はとにかくFalseに評価されます。だから、あなたはそれが好きで呼び出すことができます。

if Myfunc(s, timeout): 
    print "success" 

追加:S.Lottで指摘したように、真のPython的な方法は、Noneを返すことです。私は文字列関連の関数で文字列を返すことを選択しますが。確かに優先事項です。

また、私はMyfuncの呼び出し側が、文字列を操作して空にするかどうかを気にしないと仮定します。呼び出し側がタイムアウトの問題などをチェックする必要がある場合は、例外を使用するかNoneを返す方がよいでしょう。

+0

このデザインの問題は、あるケースのタイムアウトとsとtestが ""と等しいことを区別しないことです。 –

+0

-1:Pythonicはまったくありません。空の文字列はまだ文字列です。どれもいいです。例外はまだまだです。 –

+0

両方の有効なポイントのgentsは、答えを編集しました。 –

3

(False、None)と(True、test)のようなタプルを返すと、それらを別々に評価し、不必要な複雑さを加えることができない場合があります。

EDIT:おそらく、シリアルポートに現れた文字列は ""(多分期待されます)ので、Trueを返すとそのように到着したと言えるでしょう。

+0

私はむしろ@jelovirtのやり方をしたいと思います:Noneをテストすることはあいまいではなく、複雑さを増すものではありません。 –

+0

私はいつも複数の値を返すためのpythonタプルが好きです。 +1。 – paxdiablo

+0

私はこのアイデアが好きです。同じ値フィールドにコントロールフラグを戻しても、私には聞こえません。 このような状況では、将来、有効な値が変更され(あなたが言ったように、nullを許可する)、制御フラグが無効になるというリスクがあります。 – Sam

5

時間内に到着した場合は文字列を返すか、タイムアウトを示す適切な例外を送出します。

+0

Pythonで例外を発生させても他の言語に比べて安価であっても、それらを使って機能を提供することは素晴らしい考えではないと思います。 – Martin

+0

+1:この場合、例外がより理にかなっています - あなたは「例外」条件 - タイムアウトがありました。 –

+0

実際、私はこのパターンをシリアルポートなどを介して通信を使用するプロジェクトで多く、非常にうまく使用しています。タイムアウト例外は再試行を処理し、条件を再送します。 – Ber

10

私は正統派のPythonデザインはNoneを返すと考えています。 manualは言う:

なし

このタイプは、単一の値を持っています。この値を持つ単一オブジェクトの があります。この オブジェクトには、 ビルトイン名なしでアクセスします。それは の多くの状況で値がないことを意味するために使用されます。例えば、 何かを明示的に返さない関数 から返されます。その真理値は偽です。

2

Berのポイントに追加するには、別のものを考慮する必要があります。空の文字列またはNoneを使用すると、 "ばか"のバグのためにドアを開いたままにします。一方、例外を発生させると、実行中の操作が強制終了され、強制実行されます。

たとえば、次のコードを考えてみます。操作がタイムアウトし、空の文字列かNoneを得た場合

result = MyFunc(s, timeout) 
if result[0] == 'a': 
    do_something() 

これは、例外が発生します。したがって、次のように変更する必要があります。

result = MyFunc(s, timeout) 
if result and result[0] == 'a': 
    do_something() 

このような変更は、コードをさらに理解しにくくする傾向があります。

もちろん、私はあなたの答えが "私はそれをしません"または "それは起こらない"と答えていると確信しています。私の答えは "あなたがいなくても、この機能を使用して実行すると、最終的にはこれを行う習慣をつけることになります。これらの種類のバグは、ほとんどの場合、あなたが通常考えないコーナーケースの結果です。

1

これはPythonジェネレータの古典的な使用例です。 yieldキーワードは一度に全部を返さずに個別のセットを反復処理するための簡単な方法を提供します:

def MyFunc(s, timeout) : 
    test = get_some_input(timeout) 
    while test.endswith(s) 
     yield test 
     test = get_some_input(timeout) 

for input in MyFunc(s, timeout): 
    print input 

ここでキー入力の終了を指定する戻り値がないです。代わりに、単にイテレータの最後に到達します。発電機の詳細についてはhereをご覧ください。

関連する問題