मैं __getattr__
कुछ फैंसी करने के लिए एक वर्ग पर विधि को ओवरराइड करना चाहता हूं, लेकिन मैं डिफ़ॉल्ट व्यवहार को तोड़ना नहीं चाहता हूं।
ऐसा करने का सही तरीका क्या है?
मैं __getattr__
कुछ फैंसी करने के लिए एक वर्ग पर विधि को ओवरराइड करना चाहता हूं, लेकिन मैं डिफ़ॉल्ट व्यवहार को तोड़ना नहीं चाहता हूं।
ऐसा करने का सही तरीका क्या है?
जवाबों:
ओवरराइडिंग __getattr__
ठीक होना चाहिए - __getattr__
केवल एक अंतिम उपाय के रूप में कहा जाता है अर्थात यदि नाम से मेल खाने वाले उदाहरण में कोई विशेषता नहीं है। उदाहरण के लिए, यदि आप पहुंचते हैं foo.bar
, तो __getattr__
केवल तभी कॉल किया जाएगा जब foo
कोई विशेषता नहीं है bar
। यदि विशेषता वह है जिसे आप संभालना नहीं चाहते, तो बढ़ाएँ AttributeError
:
class Foo(object):
def __getattr__(self, name):
if some_predicate(name):
# ...
else:
# Default behaviour
raise AttributeError
हालांकि, इसके विपरीत __getattr__
, __getattribute__
पहले कहा जाएगा (केवल नई शैली की कक्षाओं के लिए काम करता है अर्थात जो ऑब्जेक्ट से विरासत में मिलते हैं)। इस स्थिति में, आप डिफ़ॉल्ट व्यवहार को संरक्षित कर सकते हैं जैसे:
class Foo(object):
def __getattribute__(self, name):
if some_predicate(name):
# ...
else:
# Default behaviour
return object.__getattribute__(self, name)
अधिक के लिए अजगर डॉक्स देखें ।
__getattr__
- किसी भी विचार को क्या करना है? ( AttributeError: 'super' object has no attribute '__getattr__'
)
AttributeError
अपवाद आर्ग में विशेषता के संदर्भ के बिना है।
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__
होने के बजाय इसका उपयोग किया जाना चाहिएself.__class__
__repr__
माइकल उत्तर का विस्तार करने के लिए, यदि आप का उपयोग करके डिफ़ॉल्ट व्यवहार बनाए रखना चाहते हैं, तो आप __getattr__
ऐसा कर सकते हैं:
class Foo(object):
def __getattr__(self, name):
if name == 'something':
return 42
# Default behaviour
return self.__getattribute__(name)
अब अपवाद संदेश अधिक वर्णनात्मक है:
>>> 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__
और __getattribute__
?