2016-01-05 6 views
5

आइए किसी भी उपयोगकर्ता द्वारा परिभाषित पायथनिक वर्ग पर विचार करें।बिल्ट-इन फ़ंक्शन को संशोधित करना

['__class__', '__delattr__', '__dict__', '__dir__', ... '__weakref__', 'bases', 
'build_full_name', 'candidates', ... 'update_name']. 

आप विशेषताओं के 2 प्रकार देख सकते हैं इस सूची में:

  • निर्मित गुण,
  • उपयोगकर्ता परिभाषित अगर मैं dir(obect_of_class) कहते हैं, मैं अपनी विशेषताओं की सूची मिलता है।

मुझे __dir__ ओवरराइड करने की आवश्यकता है, ताकि यह केवल उपयोगकर्ता परिभाषित attribltes को वापस कर सके। मैं यह कैसे कर सकता हूँ?

यह स्पष्ट है कि अगर ओवरराइड फ़ंक्शन में मैं स्वयं को कॉल करता हूं, तो यह मुझे अनंत रिकर्सन देता है। तो, मैं इस तरह somethig करना चाहता हूँ:

def __dir__(self): 
     return list(filter(lambda x: not re.match('__\S*__', x), dir(self))) 

लेकिन अनंत रिकर्सन से बचें।

सामान्य रूप से, मैं एक अंतर्निहित फ़ंक्शन को कैसे संशोधित कर सकता हूं यदि मैं इसे स्क्रैच से नहीं लिखना चाहता हूं लेकिन मौजूदा फ़ंक्शन को संशोधित करना चाहता हूं?

+0

क्या आपने इसके बजाय 'dir (className) 'का उपयोग करने का प्रयास किया था? – DainDwarf

उत्तर

8

__dir__ के माता-पिता के कार्यान्वयन को कॉल करने के लिए super का उपयोग करें;

import re 


class AClass: 

    def __dir__(self): 
     return [x for x in super().__dir__() if not re.match(r'__\S+__$', x)] 

    def method(self): 
     pass 

>>> dir(AClass()) 
['method'] 
+0

जनरेटर का उपयोग क्यों करें 'सूची (फ़िल्टर ...)) का उपयोग करने से बेहतर है? – VeLKerr

+1

@VeLKerr, यह जनरेटर नहीं है, लेकिन एक सूची समझ है। मेरे लिए, इसे पढ़ने के लिए बहुत आसान है। – falsetru

+0

ठीक है, यह काम कर रहा है, लेकिन यह बहुत अजीब है क्योंकि 'super()' -object उपयोगकर्ता परिभाषित फ़ील्ड नहीं है। तो, क्या आप समझा सकते हैं, * क्यों * यह काम कर रहा है? – VeLKerr

2

आप dir() समारोह के लिए अपने कस्टम वर्ग पर कर या विश्व स्तर पर करना चाहते हैं: प्रत्यावर्तन से बचने के? (वर्ग केवल)

पहले दृष्टिकोण:

class MyClass: 
    def f(self): 
     return None 

    def __dir__(self): 
     return list(filter(lambda x: not re.match('__\S*__', x), super().__dir__())) 


print(dir(MyClass())) # ['f'] 

असल में यहाँ क्या किया है सुपर क्लास (नहीं वर्ग में ही) के __dir__() बुला और उपवर्ग में यह फ़िल्टर कर रही है।

दूसरा दृष्टिकोण (वैश्विक dir समारोह पीछा):

import re 


def dir(obj): 
    return list(filter(lambda x: not re.match('__\S*__', x), __builtins__.dir(obj))) 

print(dir({})) # ['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values'] 
dir() को

सभी कॉल्स यहाँ फ़िल्टर किया जाएगा। जैसा कि आप देख सकते हैं - यह अंतर्निहित प्रकार सहित सभी प्रकार के लिए काम करेगा।

+0

मैं केवल अपनी कक्षा के लिए '__dir() __' को ओवरराइड करना चाहता हूं, लेकिन वैश्विक छाया के स्पष्टीकरण के लिए बहुत बहुत धन्यवाद। अनुलेख 'सुपर()' तर्क के बिना भी मेरे लिए काम करता है (मैंने पोस्ट संपादित किया)। – VeLKerr

संबंधित मुद्दे