38

私はこのコードが正しいことを知っています:

class A:   
    def __init__(self):
        self.a = 'a'  
    def method(self):   
        print "method print"  

a = A()   
print getattr(a, 'a', 'default')   
print getattr(a, 'b', 'default')  
print getattr(a, 'method', 'default') 
getattr(a, 'method', 'default')()   

そして、これは間違っています:

# will __getattr__ affect the getattr?

class a(object):
    def __getattr__(self,name):
        return 'xxx'

print getattr(a)

これも間違っています:

a={'aa':'aaaa'}
print getattr(a,'aa')

どこで__getattr__andを使うべきgetattrですか?

4

3 に答える 3

62

アレックスの答えは良かったですが、あなたがそれを求めたのでサンプルコードを提供しました:)

class foo:
    def __init__(self):
        self.a = "a"
    def __getattr__(self, attribute):
        return "You asked for %s, but I'm giving you default" % attribute


>>> bar = foo()
>>> bar.a
'a'
>>> bar.b
"You asked for b, but I'm giving you default"
>>> getattr(bar, "a")
'a'
>>> getattr(bar, "b")
"You asked for b, but I'm giving you default"

要するに答えは

あなたが使う

__getattr__見つからない属性の処理方法を定義する

getattr属性取得する

于 2009-12-22T07:26:49.667 に答える
39

getattr(少なくとも) 2 つの引数を取る組み込み関数です: 属性を取得するオブジェクトと、属性の文字列名です。

文字列名が定数の場合、たとえば'foo'getattr(obj, 'foo')は とまったく同じですobj.foo

したがって、組み込み関数の主な使用例getattrは、属性名を定数ではなく変数として使用する場合です。2 番目の重要な使用例は、2 つだけではなく 3 つの引数を渡す場合です。この場合、属性がオブジェクトに存在しない場合、getattr例外を発生させるのではなく、3 番目の「デフォルト」の引数を返します。

__getattr__クラスで定義された特別なメソッドであり、そのクラスのインスタンスの属性が要求されたときに呼び出され、その属性を提供する他の通常の方法 (インスタンスの__dict__、スロット、プロパティなどを介して) がすべて失敗しました。たとえば、それ以外の場合は未定義の属性検索を他のオブジェクトに委譲する場合に、これを定義できます。

ビルトインは単一の引数で呼び出すことはgetattrできないため、2番目の例は間違っています。

「属性を取得」しようとしている辞書にはその属性がないため、3番目のものは失敗します。もちろん、属性から完全に切り離されたitemsがあります。

于 2009-12-22T07:14:16.307 に答える
19

__getattr__()定義できる特別なメソッド関数です。メンバー検索が失敗すると、この関数が呼び出されます。

getattr()メンバー検索を試みるために呼び出すことができる関数です。ルックアップが成功すると、メンバー (おそらくメソッド関数オブジェクト、またはデータ属性オブジェクト) を取得します。 getattr()ルックアップが失敗した場合にデフォルトを返すこともできます。

メンバー関数を宣言する__getattr__()と、時々成功させることも、毎回成功させることもできます。

class A(object):
    def __getattr__(self, name):
        return "I pretend I have an attribute called '%s'" % name

a = A()

print a.foo # prints "I pretend I have an attribute called 'foo'"

Python には、すべてのルックアップで常に__getattribute__()呼び出されるものもあります。メンバーに正常にアクセスできなくなる可能性があるため、非常に危険です。

class A(object):
    def __init__(self, value):
        self.v = value
    def __getattribute__(self, name):
        return "I pretend I have an attribute called '%s'" % name

a = A(42)

print a.v # prints "I pretend I have an attribute called 'v'"
print a.__dict__["v"] # prints "I pretend I have an attribute called '__dict__'"

おっと、AVにアクセスできなくなりました!

于 2009-12-22T07:28:59.153 に答える