2008-10-23 3 views
24

सी ++ में आप इसे बाल वर्ग में निजी घोषित करके अभिभावक के वर्ग में एक फ़ंक्शन अक्षम कर सकते हैं। यह पायथन में कैसे किया जा सकता है? अर्थात। मैं बच्चे के सार्वजनिक इंटरफ़ेस से अभिभावक के फ़ंक्शन को कैसे छिपा सकता हूं?पायथन विरासत - एक फ़ंक्शन को अक्षम करने के लिए कैसे करें

उत्तर

18

वहाँ वास्तव में किसी भी सच "निजी" नहीं कर रहे हैं जिम्मेदार बताते हैं या अजगर में तरीकों । एक बात आप कर सकते हैं बस विधि आप उपवर्ग में नहीं करना चाहती ओवरराइड, और एक अपवाद बढ़ा है: समस्या को हल करने के

>>> class Foo(object): 
...  def foo(self): 
...   print 'FOO!' 
...   
>>> class Bar(Foo): 
...  def foo(self): 
...   raise AttributeError("'Bar' object has no attribute 'foo'") 
...  
>>> b = Bar() 
>>> b.foo() 
Traceback (most recent call last): 
    File "<interactive input>", line 1, in <module> 
    File "<interactive input>", line 3, in foo 
AttributeError: 'Bar' object has no attribute 'foo' 
+0

> वास्तव में पाइथन में कोई भी वास्तविक "निजी" विशेषताओं या विधियां नहीं हैं। यही कारण है कि मैंने नहीं पूछा कि उन्हें निजी कैसे बनाया जाए, लेकिन इंटरफ़ेस से उन्हें कैसे हटाएं। उम्मीद है कि संपादित संस्करण अधिक सटीक –

+2

है, मैं सहमत हूं कि NotImplementedError शायद उपयोग करने वाला सबसे अच्छा है, लेकिन यदि आप वास्तव में विरासत विधि प्राप्त नहीं करना चाहते हैं, तो इसके बजाय AttributeError बढ़ाएं (जो माता-पिता विधि मौजूद नहीं थी)। –

+1

विशेषता Error के बारे में अच्छा बिंदु। मैं अपना उदाहरण अपडेट करूंगा। – kurosch

5
class X(object): 
    def some_function(self): 
     do_some_stuff() 

class Y(object): 
    some_function = None 

यह करने के लिए हालांकि कुछ गंदा और मुश्किल अपवादों को खोजने के लिए फेंके जाने का कारण बन सकता है ताकि आप यह कोशिश कर सकते हैं:

class X(object): 
    def some_function(self): 
     do_some_stuff() 

class Y(object): 
    def some_function(self): 
     raise NotImplementedError("function some_function not implemented") 
17

kurosch की विधि, काफी सही नहीं है क्योंकि आप अभी भी बिना b.foo उपयोग कर सकते हैं AttributeError प्राप्त करना। यदि आप फ़ंक्शन का आह्वान नहीं करते हैं, तो कोई त्रुटि नहीं होती है।

import doctest 

class Foo(object): 
    """ 
    >>> Foo().foo() 
    foo 
    """ 
    def foo(self): print 'foo' 
    def fu(self): print 'fu' 

class Bar(object): 
    """ 
    >>> b = Bar() 
    >>> b.foo() 
    Traceback (most recent call last): 
    ... 
    AttributeError 
    >>> hasattr(b, 'foo') 
    False 
    >>> hasattr(b, 'fu') 
    True 
    """ 
    def __init__(self): self._wrapped = Foo() 

    def __getattr__(self, attr_name): 
     if attr_name == 'foo': raise AttributeError 
     return getattr(self._wrapped, attr_name) 

class Baz(Foo): 
    """ 
    >>> b = Baz() 
    >>> b.foo() # doctest: +ELLIPSIS 
    Traceback (most recent call last): 
    ... 
    AttributeError... 
    >>> hasattr(b, 'foo') 
    False 
    >>> hasattr(b, 'fu') 
    True 
    """ 
    foo = property() 

if __name__ == '__main__': 
    doctest.testmod() 

बार लिपटे वस्तु का उपयोग प्रतिबंधित करने के लिए "रैप" पैटर्न का उपयोग करता: दो तरीके जिनसे मुझे लगता है कि कर सकते हैं यह करने के लिए कर रहे हैं। Martelli has a good talk इससे निपटने। बाज़ ओवरराइड करने के लिए विशेषता के लिए वर्णनकर्ता प्रोटोकॉल को लागू करने के लिए the property built-in का उपयोग करता है।

+2

खैर, निश्चित रूप से, मेरे उत्तर में यह अभी भी "दृश्यमान" है, लेकिन आप इसे "उपयोग" नहीं कर सकते क्योंकि यह अपवाद उठाएगा। एक वैध बिंदु, यद्यपि। – kurosch

+2

+1, "खाली" संपत्ति का उपयोग करने के लिए "खाली" संपत्ति का उपयोग करने के लिए एक स्मार्ट चाल क्या है! : डी – MestreLion

+0

यह माता-पिता पर परिभाषित ऑपरेटरों के उपयोग के लिए कक्षा को तोड़ देगा क्योंकि कोई सबक्लासिंग नहीं है। इसके अलावा '__getattr__' धीमा है – JBernardo

0

यह सबसे साफ तरीका है जिसे मैं जानता हूं।

विधियों को ओवरराइड करें और प्रत्येक ओवरराइड विधियों को अपनी अक्षम विधि() विधि को कॉल करें। इस तरह:

class Deck(list): 
... 
@staticmethod 
    def disabledmethods(): 
     raise Exception('Function Disabled') 
    def pop(self): Deck.disabledmethods() 
    def sort(self): Deck.disabledmethods() 
    def reverse(self): Deck.disabledmethods() 
    def __setitem__(self, loc, val): Deck.disabledmethods() 
9

kurosch के जवाब पर एक बदलाव:

class Foo(object): 
    def foo(self): 
     print 'FOO!' 

class Bar(Foo): 
    @property 
    def foo(self): 
     raise AttributeError("'Bar' object has no attribute 'foo'") 

b = Bar() 
b.foo 

यह बजाय जब विधि कहा जाता है की संपत्ति पर एक AttributeError को जन्म देती है।

मैंने इसे एक टिप्पणी में सुझाव दिया होगा लेकिन दुर्भाग्यवश इसके लिए अभी तक प्रतिष्ठा नहीं है।

+0

क्या आप 'getattr (b, "foo")' कॉल करते हैं, तो क्या यह एट्रिब्यूट एरर बढ़ाएगा? अनजाने में मेरे पास इसका परीक्षण करने के लिए यहां पाइथन इंटरप्रेटर नहीं है। –

+0

यदि आपका मतलब है 'getattr (b,' foo ')' तो हाँ यह –

+0

हां, यही मेरा मतलब था। हालांकि 'गेटैटर (बी, 'फू') आपको एक विशेषता त्रुटि भी देगा, इसलिए वहां कोई चिंता नहीं है! –

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