2017-05-15 6 views
1

私は、Pythonを習い始めはしばらく前から3.xと私は数字を追加するか、リスト、タプルとdictsを連結し、非常に簡単なコードを書いた:私の主なのPython 3.xの - 関数引数の型テスト

X = 'sth' 
def adder(*vargs): 
    if (len(vargs) == 0): 
    print('No args given. Stopping...') 
else: 
    L = list(enumerate(vargs)) 
    for i in range(len(L) - 1): 
     if (type(L[i][1]) != type(L[i + 1][1])): 
      global X 
      X = 'bad' 
      break 
    if (X == 'bad'): 
     print('Args have different types. Stopping...') 
    else: 
     if type(L[0][1]) == int:       #num 
      temp = 0 
      for i in range(len(L)): 
       temp += L[i][1] 
      print('Sum is equal to:', temp) 
     elif type(L[0][1]) == list:       #list 
      A = [] 
      for i in range(len(L)): 
       A += L[i][1] 
      print('List made is:', A) 
     elif type(L[0][1]) == tuple:      #tuple 
      A = [] 
      for i in range(len(L)): 
       A += list(L[i][1]) 
      print('Tuple made is:', tuple(A)) 
     elif type(L[0][1]) == dict:       #dict 
      A = L[0][1] 
      for i in range(len(L)): 
       A.update(L[i][1]) 
      print('Dict made is:', A) 

adder(0, 1, 2, 3, 4, 5, 6, 7) 
adder([1,2,3,4], [2,3], [5,3,2,1]) 
adder((1,2,3), (2,3,4), (2,)) 
adder(dict(a = 2, b = 433), dict(c = 22, d = 2737)) 

をこの問題は、argsが 'X'グローバルと異なる型を持つときに関数から抜け出す方法です。私はしばらく考えていましたが、私はこれをやるより簡単な方法が見えません(私は単純に結果を印刷するので、他のものを置くことはできません、おそらく私は何かを続けるおよび使用を中断する)。
私はこれを行う簡単な方法が欠けていると確信していますが、私はそれを得ることができません。 ありがとうございます。ここに他のコードに関するアドバイスがありましたら、私はさらなる助けに感謝します。私はおそらく、以前のC++コーディングから来る多くの悪い非Pythonの習慣を持っています。

答えて

0

ここで私が作ったいくつかの変更がありますが、これを少しきれいにして、グローバル変数の必要性を取り除くと思います。

def adder(*vargs): 
    if len(vargs) == 0: 
     return None # could raise ValueError 

    mytype = type(vargs[0]) 
    if not all(type(x) == mytype for x in vargs): 
     raise ValueError('Args have different types.') 

    if mytype is int: 
     print('Sum is equal to:', sum(vargs)) 
    elif mytype is list or mytype is tuple: 
     out = [] 
     for item in vargs: 
      out += item 
     if mytype is list: 
      print('List made is:', out) 
     else: 
      print('Tuple made is:', tuple(out)) 
    elif mytype is dict: 
     out = {} 
     for i in vargs: 
      out.update(i) 
     print('Dict made is:', out) 

adder(0, 1, 2, 3, 4, 5, 6, 7) 
adder([1,2,3,4], [2,3], [5,3,2,1]) 
adder((1,2,3), (2,3,4), (2,)) 
adder(dict(a = 2, b = 433), dict(c = 22, d = 2737)) 

私はもう少し「ピジョンソニック」と思ういくつかの改良も加えました。不正な引数がある場合は、一般的に短期cuircuitだろうとだけとValueErrorを投げる

for item in list: 
    print(item) 

の代わりに、このような関数で

for i in range(len(list)): 
    print(list[i]) 

例えば。

if bad_condition: 
    raise ValueError('Args have different types.') 
+0

コードは今や良く見え、型チェックvarはifの外にあるので、グローバルの必要はありません。 あなたの答えをありがとう、それは速かった! – Sqoshu

+0

私はもう少し更新を加えました。リスト内の数字の合計を取得するには、sum()関数を使用します。また、all()関数を使って配列全体の状態をチェックしてみてください。この場合は、すべての型が一致していることを確認していた場所で使用しています。 – lolsborn

0

ただ、コントラストのために、ここで私にもっとニシキヘビ感じている別のバージョンは、(合理的な人々は私がOKである、私と一緒に同意しないかもしれません)です。
主な違いは、a)型の衝突が引数を組み合わせて演算子に残っていること、b)引数の型について仮定がなされていないこと、c)出力されずに結果が返されることです。これにより、異なるタイプを組み合わせることができます(たとえば、combine({}, zip('abcde', range(5))))。
引数を結合するために使用される演算子は、addまたはupdateという名前の最初の引数型のメンバ関数であることが前提です。

私は最小限の型チェックを行い、ダックタイピングを使用して有効ではありませんが予期せぬユースケースを可能にするため、このソリューションを推奨します。

from functools import reduce 
from operator import add 

def combine(*args): 
    if not args: 
     return None 
    out = type(args[0])() 
    return reduce((getattr(out, 'update', None) and (lambda d, u: [d.update(u), d][1])) 
        or add, args, out) 

print(combine(0, 1, 2, 3, 4, 5, 6, 7)) 
print(combine([1,2,3,4], [2,3], [5,3,2,1])) 
print(combine((1,2,3), (2,3,4), (2,))) 
print(combine(dict(a = 2, b = 433), dict(c = 22, d = 2737))) 
print(combine({}, zip('abcde', range(5)))) 
+0

3.xでコンパイルされた場合のコードエラー(印刷をかっこで囲む必要があります)。 私がここで問題になっているのは、最後に電話をかけたようなものを使用すると、結果が実際には予想外であるため、ユーザーが自分が望むものを手に入れたかどうかを確認する方が良いのではないかと思います。実際のアプリケーションを使用する場合、予期しない結果に対処する方法ですか? このソリューションは私にとっては複雑なようですが、私はこのような高度なコードの準備ができているかわかりませんが、あなたの答えに感謝します。 – Sqoshu

+0

前のコメントはもう編集できません。 私が正しく理解していれば、reduceの最初の部分はdict型を扱います - getattrは型が 'update'メソッドを持っているかどうかをチェックしますが、ここでlambda funcは正確に何を説明できますか?私は '[d.update(u)、d] [1]'がどのように動作しているか完全に理解していません。 – Sqoshu

+0

私は印刷行を修正しました(私は遅く追加しました;残りはPython 3で正しく動作します)。私は最後の行の結果が予期しないものであるかどうかはわかりません。戻り値の型は最初の引数の型と同じなので、ユーザーは要求されたものを正確に取得しています。私が従った原則は最低限の条件しか持たない方が良いということです。これにより、元の著者が見出したものだけでなく、すべての有効な使用が許可されます。 – cco

関連する問題