2013-02-17 25 views
26

私はオブジェクト "myobject"を持っています。それはNoneを返すかもしれません。それはNoneを返した場合、それは "idを" 属性を返しません。属性のデフォルト値を返すにはどうすればよいですか?

a = myobject.id 

のでMyObjectには、はAttributeErrorで結果上記stament Noneとき:

AttributeError: 'NoneType' object has no attribute 'id' 

myobjectがNone場合には、私は "a"をNoneと等しくします。どのように私は1つのライン文でこの例外を避けるか、など:中間の値である場合、三項演算子は最初の式を返し

a = myobject.id if myobject is not None else None 

a= default(myobject.id, None) 

答えて

71

あなたが直接idの値を取得するのではなく、getattrラッパーを使用する必要があり、仕事と明確であるだろう。

a = getattr(myobject, 'id', None) 

これは言ってようなものです「私はオブジェクトmyobjectから属性idを取得したいが、オブジェクトmyobjectの内部には、属性idがない場合は、代わりにNoneを返します。」しかしそれは効率的にそれを行います。インプレースのようなものです

Reduce:OPの要求ごととして

a = myobject.getattr('id', None) 

'deep getattr'

def deepgetattr(obj, attr): 
    """Recurses through an attribute chain to get the ultimate value.""" 
    return reduce(getattr, attr.split('.'), obj) 
# usage: 
print deepgetattr(universe, 'galaxy.solarsystem.planet.name') 

簡単な説明

一部のオブジェクトもgetattrアクセスの次の形式をサポート再帰関数。

a = getattr(getattr(myobject, 'id', None), 'number', None)

+1

+1これはおそらく私がそれを考えなかった理由を知らない最良のアイデアです –

+0

ハ、ありがとう、恥知らずの自己昇進のためにあなたの推薦を使用するつもりです:P –

+0

@Inbarローズそしてもし私がobta同じように、 'a = myobject.id.number'のように属性の属性に? – alwbtc

10

最も簡単な方法は、三項演算子を使用することですそうでなければ、後者の式を返します。あなたも、例外を使用して、別の方法でこれを行うことができることを

注:

try: 
    a = myobject.id 
except AttributeError: 
    a = None 

これは、それが許可よりも許しを求めることが容易だというPython的に理想的なフィット - 何が最善かは状況に依存します。

+0

はそれが速い評価していますか?私はこのチェックを行うために30000のオブジェクトを持っています。 – alwbtc

+0

@alwbtc試してみてください。 'timeit'モジュールをチェックしてください。値の大部分が「None」になる可能性が高いと思われる場合、最初の方法はおそらく速く、そうでない場合は秒を使用します。 –

+0

OK、値はあまり大きくありません。だから私は2番目の方法を使用します。しかし、私はまた、1つのライナーからなるコードが必要です。あなたは一行の声明がより良いと思いませんか? – alwbtc

0
try: 
    a = myobject.id 
except AttributeError: 
    a = None 

もIMO

+0

私はPythonの専門家ではありませんが、私が扱っていたほとんどの言語では、 "except"ステートメントでは追加コストがかかりません。このような単純なケースでは、 "getattr –

+0

未熟な最適化、良い若者、早すぎる最適化 – hd1

+2

これは時期尚早の最適化ではありません。通常の動作を処理するために例外を使用することは、一般的に悪いスタイルと見なされます(これはコストがかからないと仮定します)。 – francoisr

0
a=myobect.id if myobject else None 
1
:何それは、この場合に行うことは、あなたの質問に、それはこのようになるので、 obj(宇宙)で始まり、その後、再帰的にそれぞれのより深いあなたは getattrを使用してアクセスしようとする属性を取得しています

Help on built-in function getattr in module builtins:

getattr(...) 
    getattr(object, name[, default]) -> value 

Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y. When a default argument is given, it is returned when the attribute doesn't exist; without it, an exception is raised in that case.

動作するはずです後:私のオブジェクトクラスで

a = getattr(myobject, 'id', None) 
6

あなたが

を無効に置くことができます
class Foo(object): 
    def __getattribute__(self, name): 
     if not name in self; 
     return None; 
     else: 
     # Default behaviour 
     return object.__getattribute__(self, name) 
0

あなたは(Black Diamond's answerのように)myobjectのクラスの定義の中で問題を解決したい場合は、単にNoneを返すように__getattr__を定義することができます。

class Myobject: 
    def __getattr__(self, name): 
     return None 

__getattr__のみときに呼び出されるので、これは動作します存在しない属性にアクセスしようとすると、属性の名前にかかわらず常に__getattribute__が最初に呼び出されます。 (もthis SO post参照。)

試すには:

myobject = Myobject() 
print myobject.id 
myobject.id = 7 
print myobject.id 
関連する問題