私は、3つの異なる方法で名前を付けることができるpseudoまたはspecial属性を持つオブジェクトを持っています(注:オブジェクトを生成するコードを制御しません)
属性の値(設定されているものによって異なります)はまったく同じであり、さらに処理するためにそれを取得する必要があるため、データのソースに応じて、次のようにすることができます。
>>> obj.a
'value'
>>> obj.b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: Obj instance has no attribute 'b'
>>> obj.c
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: Obj instance has no attribute 'c'
または
>>> obj.a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: Obj instance has no attribute 'a'
>>> obj.b
'value'
>>> obj.c
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: Obj instance has no attribute 'c'
または
>>> obj.a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: Obj instance has no attribute 'a'
>>> obj.b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: Obj instance has no attribute 'b'
>>> obj.c
'value'
'value'
を取得することに興味がありますが、残念ながら__dict__
プロパティはそのオブジェクトに存在しません。したがって、その値を取得するために私がやったことは、getattr
呼び出しをたくさん行うことでした。可能性が3つだけであると仮定すると、コードは次のようになります。
>>> g = lambda o, l: getattr(o, l[0], getattr(o, l[1], getattr(o, l[2], None)))
>>> g(obj, ('a', 'b', 'c'))
'value'
さて、これにもっと良い方法があるかどうか知りたいですか?私は自分がやったことを100%確信しているので:)
前もって感謝します
どうですか:
for name in 'a', 'b', 'c':
try:
thing = getattr(obj, name)
except AttributeError:
pass
else:
break
これには、任意の数のアイテムを処理できるという利点があります。
def getfirstattr(obj, *attrs):
return next((getattr(obj, attr) for attr in attrs
if hasattr(obj, attr)), None)
これにはveryマイナーな欠点があり、最終値に対して2つのルックアップを実行します。1回は属性が存在することを確認するため、もう1回は実際に値を取得するためです。これは、ネストされたジェネレータ式を使用することで回避できます。
def getfirstattr(obj, *attrs):
return next((val for val in (getattr(obj, attr, None) for attr in attrs)
if val is not None), None)
しかし、私はそれが大したことだとは本当に感じていません。ジェネレータ式は、ダブルルックアップを使用した場合でも、単純な古いループよりも高速になる可能性があります。
Dirを使用すると、基本的に同じものが得られると思います__dict__
通常は.。
targetValue = "value"
for k in dir(obj):
if getattr(obj,k) == targetValue:
print "%s=%s"%(k,targetValue)
何かのようなもの
>>> class x:
... a = "value"
...
>>> dir(x)
['__doc__', '__module__', 'a']
>>> X = x()
>>> dir(X)
['__doc__', '__module__', 'a']
>>> for k in dir(X):
... if getattr(X,k) == "value":
... print "%s=%s"%(k,getattr(X,k))
...
a=value
>>>
オブジェクトの構造によっては、これを行うためのより良い方法があるかもしれませんが、他に何も知らないので、任意の数の引数で機能することを除いて、現在のソリューションとまったく同じように機能する再帰ソリューションを次に示します。
g = lambda o, l: getattr(o, l[0], g(o, l[1:])) if l else None