2012-03-15 3 views
6

में विधि ओवरलोडिंग मुझे अनावृत विधि first पर कॉल करने की आवश्यकता है, लेकिन यह भी first पैरामीटरकृत है, लेकिन यह एक त्रुटि दे रहा है।पायथन

>>> class A: 
...  def first(self): 
...    print 'first method' 
...  def first(self,f): 
...    print 'first met',f 
... 
>>> a=A() 
>>> a.first() 
Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
TypeError: first() takes exactly 2 arguments (1 given) 

क्या जावा में पाइथन में विधि अधिभार करना संभव है?

+1

* कृपया * वस्तु से विरासत! आप वास्तव में * पुराने शैली की कक्षा नहीं चाहते हैं, है ना? (यह पायथन 3 में एक गैर-मुद्दा होगा, लेकिन आपके प्रिंट स्टेटमेंट्स मुझे बताते हैं कि आप पाइथन 2 का उपयोग कर रहे हैं।) –

उत्तर

9

आपकी दूसरी first विधि मूल first विधि को ओवरराइड कर रही है। पायथन में, जावा में जैसे ही ओवरलोडेड विधियों को बनाना संभव नहीं है।

हालांकि, आप वैकल्पिक और/या कीवर्ड-आधारित तर्कों के साथ विधियां बना सकते हैं और तदनुसार उनको संसाधित कर सकते हैं। यहाँ एक उदाहरण है:

class A: 
    def first(self, f=None): 
     if f is not None: 
      print 'first met', f 
     else: 
      print 'first method' 

उपयोग:

a = A() 
a.first() 
a.first('something') 
+2

हाँ। पायथन की डिफ़ॉल्ट तर्क शैली वास्तव में अधिक संक्षेप में है, और, आईएमओ, तर्कों की घटती संख्याओं के साथ ओवरराइड विधियों की जावा-स्टाइल विशाल सूची को पढ़ने और बनाए रखने में आसान है। –

0

अजगर सी ++ नहीं है या जावा; आप उसी तरह से विधियों को अधिभारित नहीं कर सकते हैं।

सच में, तुम क्या चाहते करने के लिए एक ही रास्ता उपस्थिति या दूसरा पैरामीटर के अभाव के लिए परीक्षण करने के लिए है:

class A: 
    def first(self, f=None): 
     if f is None: 
     print 'first method' 
     else: 
     print 'first met',f 

आपने अभी तक अधिक परिष्कृत हो सकता है और f के प्रकार की जाँच लेकिन यह है कि हो सकता है खतरनाक, और हमेशा "पायथनिक" नहीं है। (हालांकि, यह उल्लेख किया जाना चाहिए कि पाइथन 3 में function annotations के लिए एक उपयोग केस इस तरह के "जेनेरिक प्रोग्रामिंग" की अनुमति देना है।)

0

हालांकि ओवरलोडेड विधियों का उपयोग करने के लिए प्रतीत होता है कि एक सिस्टम बनाना संभव है, यह थोड़ा सा है शामिल, और आमतौर पर आवश्यक नहीं है।

सामान्य मुहावरा तो की तरह, None को संभवतः अनावश्यक पैरामीटर डिफ़ॉल्ट है:

class A: 
    def first(self, f=None): 
     if f is None: 
      print 'first method' 
     else: 
      print 'first met',f 

अपने मामले, जहाँ आप या नहीं, यह है कि विधि के लिए पहली कॉल है पर आधारित अलग व्यवहार चाहते हैं, यह मैं क्या कर सकता है:

class A: 
    def first(self): 
     print 'first method' 
     self.first = self._first 
    def _first(self, f):     # '_' is convention for private name 
     print 'first met',f 

और नमूना उत्पादन:

a = A() 
a.first() 
a.first(3) 

प्रिंट:

first method 
first met 3 
5

पायथन फ़ंक्शन ओवरलोडिंग नहीं करता है। यह एक कमजोर टाइप की गई भाषा होने का एक परिणाम है। इसके बजाय आप तर्क तर्क में अज्ञात संख्या निर्दिष्ट कर सकते हैं और उनकी व्याख्या के साथ सौदा कर सकते हैं।

कुछ तरीके हैं जो आप कर सकते हैं। आप विशिष्ट वैकल्पिक तर्क निर्दिष्ट कर सकते हैं: यह कॉलिंग

def func1(arg1, arg2=None): 
    if arg2 != None: 
     print "%s %s" % (arg1, arg2) 
    else: 
     print "%s" % (arg1) 

हम पाते हैं:

>>> func1(1, 2) 
1 2 

या आप अनाम तर्कों की संख्या ज्ञात नहीं निर्दिष्ट कर सकते हैं (अर्थातएक सरणी में पारित तर्क):

def func2(arg1, *args): 
    if args: 
     for item in args: 
      print item 
    else: 
     print arg1 

यह कॉलिंग हम पाते हैं:

>>> func2(1, 2, 3, 4, 5) 
2 
3 
4 
5 

या आप नामित तर्कों की एक अज्ञात नंबर (यानी तर्क एक शब्दकोश में पारित) निर्दिष्ट कर सकते हैं:

def func3(arg1, **args): 
    if args: 
     for k, v in args.items(): 
      print "%s %s" % (k, v) 
    else: 
     print arg1 

इसे कॉल करना हमें मिलता है:

>>> func3(1, arg2=2, arg3=3) 
arg2 2 
arg3 3 

आप इन निर्माणों का उपयोग उस व्यवहार को उत्पन्न करने के लिए कर सकते हैं जिसे आप ओवरलोडिंग में ढूंढ रहे थे।

+1

आपका 'func1() 'एक कॉल के रूप में व्यवहार नहीं करता है जब इसे' func1 (1, 0)' – bgporter

+0

आह हाँ, अच्छी पकड़ के रूप में जाना जाता है। परिवर्तन किया – cjm

3

आमतौर पर आप किसी दिए गए नाम के साथ कक्षा में एक विधि को परिभाषित कर सकते हैं। आपके उदाहरण में पहले 2 तर्क() विधि पहले 1 तर्क को ओवरराइट करें()। यदि आप एक ही नाम के साथ दो विधियों को चाहते हैं, तो पाइथन 3 में आपको functools.singledispatch का उपयोग करना होगा, और उदाहरण विधि का नाम अपने स्थैतिक विधि प्रेषक को मानचित्र करें, ओच!

कहा, मैं वास्तव में OO प्रोग्रामिंग में निहित गतिशील प्रेषण पसंद है, और मैं इसे() फ़ंक्शन, जो बार-बार और विस्तार करने के लिए भंगुर है 'गुरु' के कुछ प्रकार में मैनुअल प्रेषण तर्क लेखन पहले की तुलना में क्लीनर पाते हैं।

चुनौती प्रश्न: एफ़र्स्ट (ए तर्क) जैसी एक और विधि जोड़ें।

यदि आप ऐसा करने का प्रयास करते हैं तो शायद आप पाइथन प्रकार प्रणाली के बारे में बहुत कुछ सीखेंगे!

#!/opt/local/bin/python3.4 

from functools import singledispatch; 

class A(object): 

    # default method handles dispatch for undefined types 
    # note reversed positional args to match single dispatch functools 
    @singledispatch 
    def _first(arg, self): 
     raise TypeError("no match for A._first(%s)" % type(arg)); 

    # adapter maps instance call to (reversed) static method call 
    def first(self, arg = None): return A._first(arg, self); 

    # def first() 
    @_first.register(type(None)) 
    def _(none, self): 
     print("A.first() called"); 

    # def first(float f) 
    @_first.register(float) 
    def _(f, self): 
     print("A.first(float %s) called" % f); 

a = A(); 
a.first();    # A.first() called 
a.first(None);   # A.first() called 
a.first(3.14);   # A.first(float 3.14) called 

class B(object): pass; 
b = B();     
try: a.first(b);  # no match for A._first(<class '__main__.B'>) 
except TypeError as ex: print(ex); 
+0

आप अच्छे हैं! अच्छा उदाहरण – madjardi

+0

ओह, यह * चालाक * :-) है –

1

चेक इस कोड को अगर यह उपयोगी है:

from math import pi 

class Geometry: 

    def area(self,length = None,breadth = None,side = None,radius = None): 
     self.length = length 
     self.breadth = breadth 
     self.side = side 
     self.radius = radius 

     if length != None and breadth != None: 
      return length * breadth 
     elif side != None: 
      return side * side 
     else: 
      return pi * radius * radius 

obj1 = Geometry() 
print('Area of rectangle is {0}.'.format(obj1.area(length=5,breadth=4))) 
print('Area of square is {0}.'.format(obj1.area(side=5))) 
print('Area of circle is {0:.6}.'.format(obj1.area(radius=10)))