Ich möchte die __getattr__
Methode für eine Klasse überschreiben , um etwas Besonderes zu tun, aber ich möchte das Standardverhalten nicht brechen.
Was ist der richtige Weg, um dies zu tun?
Ich möchte die __getattr__
Methode für eine Klasse überschreiben , um etwas Besonderes zu tun, aber ich möchte das Standardverhalten nicht brechen.
Was ist der richtige Weg, um dies zu tun?
Antworten:
Das Überschreiben __getattr__
sollte in Ordnung sein - __getattr__
wird nur als letzter Ausweg aufgerufen, dh wenn die Instanz keine Attribute enthält, die mit dem Namen übereinstimmen. Wenn Sie beispielsweise darauf zugreifen foo.bar
, __getattr__
wird nur aufgerufen, wenn foo
kein Attribut aufgerufen wurde bar
. Wenn das Attribut eines ist, das Sie nicht verarbeiten möchten, erhöhen Sie AttributeError
:
class Foo(object):
def __getattr__(self, name):
if some_predicate(name):
# ...
else:
# Default behaviour
raise AttributeError
Doch im Gegensatz zu __getattr__
, __getattribute__
zunächst wird (funktioniert nur für neue Stilklassen diejenigen also , dass vererben Objekt) bezeichnet. In diesem Fall können Sie das Standardverhalten wie folgt beibehalten:
class Foo(object):
def __getattribute__(self, name):
if some_predicate(name):
# ...
else:
# Default behaviour
return object.__getattribute__(self, name)
Weitere Informationen finden Sie in den Python-Dokumenten .
__getattr__
- irgendwelche Ideen, was zu tun ist? ( AttributeError: 'super' object has no attribute '__getattr__'
)
AttributeError
ohne den Kontext des Attributs in den Ausnahmeargumenten.
class A(object):
def __init__(self):
self.a = 42
def __getattr__(self, attr):
if attr in ["b", "c"]:
return 42
raise AttributeError("%r object has no attribute %r" %
(self.__class__.__name__, attr))
>>> a = A()
>>> a.a
42
>>> a.b
42
>>> a.missing
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in __getattr__
AttributeError: 'A' object has no attribute 'missing'
>>> hasattr(a, "b")
True
>>> hasattr(a, "missing")
False
self.__class__.__name__
sollte verwendet werden, anstatt für den self.__class__
Fall, dass die Klasse überschreibt__repr__
Um die Michael-Antwort zu erweitern __getattr__
, können Sie Folgendes tun , wenn Sie das Standardverhalten beibehalten möchten :
class Foo(object):
def __getattr__(self, name):
if name == 'something':
return 42
# Default behaviour
return self.__getattribute__(name)
Jetzt ist die Ausnahmemeldung aussagekräftiger:
>>> foo.something
42
>>> foo.error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in __getattr__
AttributeError: 'Foo' object has no attribute 'error'
__getattr__
und __getattribute__
?