7

DBテーブルのリストをパラメーターとして取得し、これらのテーブルで実行されるコマンド文字列を返す関数があります。例:

pg_dump( file='/tmp/dump.sql',
         tables=('stack', 'overflow'),
         port=5434
         name=europe)

次のようなものを返す必要があります:

pg_dump -t stack -t overflow -f /tmp/dump.sql -p 5434 europe

これはを使用して行われtables_string='-t '+' -t '.join(tables)ます。

関数が(タプル)のtables=('stackoverflow')代わりに(文字列)で呼び出されると、楽しみが始まります。これにより、次のようになります。tables=('stackoverflow',)

pg_dump -t s -t t -t a -t c -t k -t o -t v -t e -t r -t f -t l -t o -t w
        -f /tmp/dump.sql -p 5434 europe

文字列自体が繰り返されているためです。

このSOの質問は、型にassertを使用することを示唆していますが、duck-typeの規則に違反しているため、Pythonicで十分かどうかはわかりません。

洞察はありますか?

アダム

4

4 に答える 4

6

この場合、型をアサートすることが適切と思われます - ダックタイピングのために正当と思われる一般的な誤用を処理します。

この一般的なケースを処理する別の方法は、文字列をテストし、特殊なケースとして正しく処理することです。

最後に、テーブル名を位置パラメーターとして渡すことをお勧めします。これにより、このシナリオの可能性が低くなります。

def pg_dump(*tables, **kwargs):
  file = kwargs['file']
  port = kwargs['port']
  name = kwargs['name']
  ...

pg_dump('stack', 'overflow', file='/tmp/dump.sql', port=5434, name='europe')
于 2010-11-21T10:52:44.630 に答える
2

ABC を使用して、オブジェクトが反復可能であるが文字列ではないことをアサートできます。

from types import StringType
from collections import Iterable
assert isinstance(x, Iterable) and not isinstance(x, StringType)
于 2010-11-21T12:37:13.963 に答える
1

引数がシーケンス(リストまたはタプル)であるか文字列であるかを検出するための一般的なPythonイディオムは、次の__iter__属性があるかどうかを確認することです。

def func(arg):
    if hasattr(arg, '__iter__'):
        print repr(arg), 'has __iter__ attribute'
    else:
        print repr(arg), 'has no __iter__ attribute'

func('abc')
# 'abc' has no __iter__

func(('abc'))
# 'abc' has no __iter__

func(('abc',))
# ('abc',) has __iter__

シーケンスでない場合は、コードの残りの部分を単純化するために、シーケンスを1つに変更することも一般的です(これは、1種類のことだけを処理する必要があります)。サンプルでは、​​単純なで実行できた可能性がありますarg = [arg]

于 2010-11-21T11:02:10.940 に答える
0

タプルではなくリストを使用できませんか?

pg_dump( file='/tmp/dump.sql',
         tables=['stack', 'overflow'],
         port=5434,
         name='europe')
于 2010-11-21T10:49:53.607 に答える