नीचे से super(B, self).test()
->bubble()
करने का एक छोटा रास्ता मिला।
(एकाधिक वंशानुक्रम के साथ काम करता, तर्क की आवश्यकता नहीं है, correcly उप-वर्गों के साथ बर्ताव करता है)
समाधान inspect.getmro(type(back_self))
(जहां back_self
कॉल प्राप्त करने वाला से एक self
है) का इस्तेमाल किया गया है, तो cls
के रूप में यह पुनरावृत्ति method_name in cls.__dict__
साथ और यह सत्यापित करना कि हमारे पास कोड संदर्भ इस वर्ग में है (find_class_by_code_object(self)
नेस्टेड फ़ंक्शन में महसूस किया गया है)।
bubble()
आसानी से *args, **kwargs
के साथ बढ़ाया जा सकता है।
import inspect
def bubble(*args, **kwargs):
def find_class_by_code_object(back_self, method_name, code):
for cls in inspect.getmro(type(back_self)):
if method_name in cls.__dict__:
method_fun = getattr(cls, method_name)
if method_fun.im_func.func_code is code:
return cls
frame = inspect.currentframe().f_back
back_self = frame.f_locals['self']
method_name = frame.f_code.co_name
for _ in xrange(5):
code = frame.f_code
cls = find_class_by_code_object(back_self, method_name, code)
if cls:
super_ = super(cls, back_self)
return getattr(super_, method_name)(*args, **kwargs)
try:
frame = frame.f_back
except:
return
class A(object):
def test(self):
print "A.test()"
class B(A):
def test(self):
# instead of "super(B, self).test()" we can do
bubble()
class C(B):
pass
c = C()
c.test() # works!
b = B()
b.test() # works!
यदि किसी के पास कोई बेहतर विचार है, तो इसे सुनें।
ज्ञात बग: (धन्यवाद डबलपी) यदि C.test = B.test
-> "अनंत" रिकर्सन। यद्यपि यह वास्तव में एक विधि के लिए बाल वर्ग के लिए यथार्थवादी लगता है, यह =
'माता-पिता से एक एड है।
ज्ञात bug2: (धन्यवाद doublep) सजाया तरीकों से काम नहीं करेगा (शायद unfixable, के बाद से डेकोरेटर को बंद करने देता है) ... for _ in xrange(5)
साथ फिक्स्ड डेकोरेटर समस्याओं: ... frame = frame.f_back
- 5 संभाल लेंगे सजावट, यदि आवश्यक हो तो वृद्धि। मुझे पायथन पसंद है!
प्रदर्शन super()
कॉल से 5 गुना अधिक खराब है, लेकिन हम प्रति सेकंड एक लाख कॉल बनाम 200K कॉल के बारे में बात कर रहे हैं, अगर यह आपके सबसे अच्छे लूप में नहीं है - चिंता करने का कोई कारण नहीं है।
यदि मैं पूछ सकता हूं ... आपको इसके लिए क्या चाहिए? क्योंकि मैं शायद ही सोचता हूं कि ऐसा कुछ भी किसी भी चीज़ के लिए सबसे अच्छा तरीका हो सकता है। – Wolph
मैं वास्तव में कुछ प्रकार के सरल 'बबल()' कॉल वाले उपयोगकर्ताओं के लिए 'सुपर (बी, स्वयं) .test() 'को सरल बनाने की कोशिश कर रहा हूं। असल में, मुझे पहले से ही एक रास्ता मिल गया है। –
क्या आप 'सुपर (स्वयं .__ class__, self) .test() 'नहीं कर सका? – Wolph