2012-02-27 4 views
4

私はむしろPythonを初めて使っています。最近、私はPythonのクラス概念を検討していました。私が書いた2つのスクリプトでは、(ArcGisの方言で)SQLステートメントをまとめるクラスを定義すると便利だと思いました。本当に素晴らしいことはありません。ここに私が思いついたのがあります。私は2つのことを求めている:第一に、一般的な欠陥?改善のための提案?第二に、私は最後の関数def constructorのコードにちょっと固執しています。実際には、リストではなく、辞書からタプルを返したいと思います。しかし、リストの理解はいいです。では、発電機はどうですか?私はそれを行う方法を正確に把握することはできません...リストの理解の代わりにジェネレータ?そして、どこでクラスを改善できますか?

class ArcSql: 
    type_book = {'str':("'","'"), 'int':("", "")} 
    format_book = dict(shp=("'","'"), GDB=("[","]")) 

    def __init__(self,colom_name, values_list, value_type = 'str', arc_format ='shp'): 
     self.colom = colom_name 
     self.values = values_list 
     self.valtype = self.constructor(type_book, value_type) 
     self.aformat = self.constructor(format_book, arc_format) 
     self.colom_formated = str(self.aformat[0][0]) + self.colom + str(self.aformat[0][1]) 

    def statement(self): 
     temp_state = [] 
     connector = "'OR' " 
     count_values = len(self.values) 
     if count_values == 0: 
      return("error, not enough values...") 
     else: 
      for v in self.values: 
       x = self.colom_formated + " = " + str(self.valtype[0][0]) + v + str(self.valtype[0][1]) + ' ' + connector 
       temp_state.append(str(x)) 
     state = "".join(temp_state)[:-5]    
     return(str(state)) 

    def constructor(self, book, book_key): 
     return([v for k,v in book.iteritems() if k==book_key]) 
+0

: ' "%S%S%S" %(self.aformat [0:あなたはビット文字列置換を使用して' colom_formated'ラインを片付けることができ] [0]、self.colom、self.aformat [0] [1]) 'これは高速です。 'x = ...'行についても同じことが言えます。 'if count_values == 0:'を比較すると非常にpythonではありません - 'boolean([])'は 'False'に等しいので、' self.values'がその仕事をします。 'str()'へのすべての呼び出しはあまりにも過剰です - すでに文字列を扱っているので、それらを再度変換する必要はありません。 –

+0

'return'はキーワードであり、関数ではありません(考えれば、どのようにそのような関数が実装されるのでしょうか?)ので、返すものの周りのかっこは不要です(そして、かなり醜いと見なされます)。また、行に対応すると仮定して、* column *と書かれています。 –

+0

ありがとう、非常に有用な提案。私は個人的に文字列の置換が本当に好きではありませんが、コードを読みにくくすると思います。しかし、それは私のコーディング経験と関係しているかもしれません。とにかく、あなたの助けをありがとう、それは非常に感謝しています! – LarsVegas

答えて

4

最初の質問は、codereview siteでよく聞かれるはずです。

あなたの2番目の質問については、次のように発電機を使用することができます。

def constructor(self, book, book_key): 
    for k, v in book.iteritems(): 
     if k==book_Key: 
      yield v 

... 

for value in obj.constructor(book ,book_key): 
    # Do whatever you need with value 

をとにかく、私の理解では、そのような場合には、リスト内包から1つの結果だけを取得するつもりだということです。

nextが内蔵されているイテレータを使い果たした場合はデフォルト値が渡されない場合、例外が発生します(イテレータまたは渡されたデフォルト値(この場合は None)の次の値を返すために
def constructor(self, book, book_key): 
    return next(v for k, v in book.iteritems() if k==book_key, None) 

... 

value = obj.constructor(book ,book_key) 
if value is not None: 
    # Do whatever you need with value 

その場合)。

+0

こんにちは。速い答えをありがとう、皆さんは大きな助けをしています!まあ、私は本当に 'None'の部分を取得していません。これはvの代用品ですか?エラー処理の手助けをしますか? – LarsVegas

+0

はい、デフォルト値が定義されておらず、 'k == book_key'を満たす値がない場合、' StopIteration'例外が送出されます。それ以外の場合(デフォルト値が定義されている場合)、デフォルト値が定義されます。例外またはデフォルト値のどちらを優先するかは、問題と作業しているコードによって異なります。 – jcollado

3

あなたは簡単ジェネレータ作るために、ちょうど()ため[]を交換することにより、発電機にあなたのリスト内包を変更し、ためreturnを交換することができます発電キーワードyield

yield (k,v in book.iteritems() if k==book_key) 

今だけ1タプルを返す必要があります - あなたが(リストとして)もっと欲しい場合は、list(constructor())を呼び出す必要があります。

+0

これは私が試みたものです。しかし 'self.valtype'はジェネレータオブジェクトになり、タプルにアクセスする方法について私の頭を得ることはできません... – LarsVegas

+0

@larsvegasああ、jcolladoの答えのように、ジェネレータで' next() 'を呼んでください。 –

1
def constructor(self, book, book_key): 
    return([v for k,v in book.iteritems() if k==book_key]) 

bookが辞書の場合、そのキーは一意です。では、なぜこの言葉を反復してその価値を見いだすのでしょうか?

なぜ:改善の方法により、

def constructor(self, book, book_key): 
    return (book[book_key],) 
関連する問題