4

私は深くネストされた辞書を持っています(jsonから、instagram APIからデコードされました)。私の最初のコードは次のようなものでした:

caption = post['caption']['text']

ただし、「キャプション」キーまたは「テキスト」キーが存在しない場合は、NoneType または KeyError エラーがスローされます。

だから私はこれを思いついた:

caption = post.get('caption', {}).get("text")

これは機能しますが、そのスタイルについてはわかりません。たとえば、取得しようとしている、より深くネストされた属性の 1 つにこの手法を適用すると、見た目がかなり悪くなります。

image_url = post.get('images',{}).get('standard_resolution',{}).get('url')

これを書くためのより良い、よりpythonicな方法はありますか?私の目標は、データがある場合はデータを取得することですが、データがない場合は実行を停止することではありません。

ありがとう!

4

4 に答える 4

11

最も Pythonic な方法は、単純に以下をキャッチすることKeyErrorです。

try:
    caption = post['caption']['text']
except KeyError:
    caption = None

これは単純で明白で、Python プログラマーにはすぐに理解できます。

于 2013-02-23T03:43:13.020 に答える
2

このようなことについてどう思いますか

if 'caption' in post:
    caption = post['caption']['text']

しかし、それも崩壊し始めます

if 'images' in post and 'standard_resolution' in post['images']:
    image_url = post['images']['standard_resolution']['url']

したがって、最も Pythonic な方法は、許可ではなく許しを求めることだと思います

try:
    image_url = post['images']['standard_resolution']['url']
except KeyError:
    image_url = None
于 2013-02-23T03:38:54.513 に答える
-1

カスタム dict サブクラスを作成し、それに対処します。

class SafeDict(dict):
    def __getitem__(self,k):
        if k in self:
            return dict.__getitem__(self,k)
        return None


a = SafeDict({'a':'a'})
print a['a']
>> a
print a['b']
>> None

ネストされた辞書を SafeDict の別のインスタンスとして処理するカスタムinitを実行するか (これにより、それらを渡すことができます)、またはテスト (または try/except ブロック) を使用して KeyErrors を防ぐことができます。

また、オブジェクト クラスをオーバーロード__getattr__して、ドット表記で処理することもできます。私はそのアプローチを好む傾向があります (これは Pylons フレームワークで初めて見ました)

class AttributeSafeObject(object):

    def __init__(self,**kwargs):
        for key in kwargs:
            setattr(self,key,kwargs[key])

    def __getattr__(self, name):
        try:
            return object.__getattribute__(self,name)
        except AttributeError:
            return None

post = AttributeSafeObject({'a':'a'})
print post.a
>> a
print post.title
>> None
于 2013-02-23T03:58:18.447 に答える