2009-07-12 15 views
7

मुझे ऐसा नहीं लगता, लेकिन मैंने सोचा कि मैं बस मामले में पूछूंगा। उदाहरण के लिए, एक वर्ग है कि एक पूर्णांक समाहित में इस्तेमाल के लिए:क्या पाइथन में रूपांतरण ऑपरेटर हैं?

i = IntContainer(3) 
i + 5 

और मैं सिर्फ इस पूर्णांक उदाहरण में कोई दिलचस्पी नहीं हूँ, मैं कुछ साफ है और सामान्य के लिए, देख रहा था अधिभावी नहीं हर int और स्ट्रिंग विधि।

धन्यवाद, सनकियांग। यही वही है जो मैं चाहता था। मुझे एहसास नहीं हुआ कि आप इन अपरिवर्तनीय प्रकारों को घटा सकते हैं (सी ++ से आ रहे हैं)।

class IntContainer(int): 
    def __init__(self,i): 
     #do stuff here 
     self.f = 4 

    def MultiplyBy4(self): 
     #some member function 
     self *= self.f 
     return self 

print 3+IntContainer(3).MultiplyBy4() 

उत्तर

3

कभी-कभी शायद सीधे int से subclass पर्याप्त है। तो __add__ और __radd__ को महंगी कीमत की आवश्यकता नहीं है।

class IntContainer(int): 
    pass 
i = IntContainer(3) 
print i + 5 # 8 
print 4 + i # 7 

class StrContainer(str): 
    pass 
s = StrContainer(3) 
print s + '5' # 35 
print '4' + s # 43 
3

क्या आपको इसकी आवश्यकता है?

In [1]: class IntContainer(object): 
    ...:  def __init__(self, val): 
    ...:   self.val = val 
    ...:  def __add__(self, val): 
    ...:   return self.val + val 
    ...:  def __radd__(self, val): 
    ...:   return self.val + val 
    ...: 
    ...: 

In [2]: i = IntContainer(3) 

In [3]: i + 5 
Out[3]: 8 

In [4]: 
+1

वास्तव में नहीं। मैं सी ++ रूपांतरण ऑपरेटर की तरह कुछ ढूंढ रहा था, जो बुद्धिमानी से कंटेनर ऑब्जेक्ट को अभिव्यक्तियों में जो कुछ भी शामिल करता है उसे बदल देता है। – Alex

+0

यह "5 + मैं" के लिए असफल हो जाएगा, मुझे विश्वास है। – ars

+0

ars, आप सही हैं, मैंने आपका जवाब देखा और मुझे याद आ रही है __radd__ ... मुझे लगता है कि मैंने अपना जवाब बदलने के बाद ठीक है ... –

11

यह आपको क्या चाहिए करना चाहिए:

class IntContainer(object): 
    def __init__(self, x): 
     self.x = x 

    def __add__(self, other): 
     # do some type checking on other 
     return self.x + other 

    def __radd__(self, other): 
     # do some type checking on other 
     return self.x + other 

आउटपुट:

In [6]: IntContainer(3) + 6 
Out[6]: 9 

In [7]: 6 + IntContainer(3) 
Out[7]: 9 

"Radd के लिए" अधिक जानकारी खोज निम्नलिखित डॉक्स में के लिए:

आप "सही इसके अलावा" के लिए इस तरह के अन्य तरीकों, "सही घटाव", आदि

यहाँ एक और एक ही ऑपरेटरों को कवर लिंक मिल जाएगा:

वैसे, पायथन में कास्टिंग ऑपरेटर हैं:

लेकिन, वे क्या आप अपने उदाहरण में की जरूरत को पूरा नहीं होगा (मूल रूप से, क्योंकि तरीकों मापदंडों के लिए किसी भी प्रकार की टिप्पणी की जरूरत नहीं है, इसलिए वहाँ परोक्ष कास्ट करने के लिए कोई अच्छा तरीका है)। तो अगर आप ऐसा कर सकते हैं:

class IntContainer2(object): 
    def __init__(self, x): 
     self.x = x 

    def __int__(self): 
     return self.x 


ic = IntContainer2(3) 
print int(ic) + 6 
print 6 + int(ic) 

लेकिन यह असफल हो जायेगी:

print ic + 6 # error: no implicit coercion 
3

आप सी में की तरह रूपांतरण ऑपरेटरों नहीं मिलेगा ++ क्योंकि अजगर मजबूत स्थिर प्रकार इस प्रकार की प्रणाली नहीं है। एकमात्र स्वचालित रूपांतरण ऑपरेटर वे हैं जो डिफ़ॉल्ट संख्यात्मक मान (int/float) को संभालते हैं; वे भाषा में पूर्वनिर्धारित हैं और बदला नहीं जा सकता है।

टाइप करें "रूपांतरण" आमतौर पर निर्माता/कारखानों द्वारा किया जाता है। इसके बाद आप अन्य कक्षाओं की तरह काम करने के लिए __add__ जैसे मानक विधियों को अधिभारित कर सकते हैं।

0

8.5 साल देर से पार्टी में आने के लिए खेद है। आप एक अपरिवर्तनीय (यानी int) से प्राप्त कर सकते हैं। आप __init__ को परिभाषित नहीं कर सकते क्योंकि अपरिवर्तनीय पहले से ही बनाया गया है और संशोधित नहीं किया जा सकता है (परिभाषा के अनुसार)। यह वह जगह है जहां __new__ काम में आता है।

class IntContainer(int): 
    def __new__ (cls, val): 
     ival = int.__new__(cls, val) 
     ival._rval = 'IntContainer(%d)' % ival 
     return ival 
    def __repr__ (self): 
     return self._rval 

In [1]: i = IntContainer(3) 

In [2]: i 
Out[2]: IntContainer(3) 

In [3]: repr(i) 
Out[3]: 'IntContainer(3)' 

In [4]: str(i) 
Out[4]: '3' 

In [5]: i + 5 
Out[5]: 8 

In [6]: 4 + i 
Out[6]: 7 

In [7]: int(i) 
Out[7]: 3 

In [8]: float(i) 
Out[8]: 3.0 

अब रूपांतरण ऑपरेटरों के बारे में आपके प्रश्न का उत्तर देने के लिए। आप __int__, __long__, __float__, और जाहिर है, __str__ भी परिभाषित कर सकते हैं। एक मनमानी वस्तु को बदलने या डालने के लिए, आपको जो भी चाहिए वो प्राप्त करने के लिए आपको अन्य ऑब्जेक्ट को संशोधित करने की आवश्यकता होगी। आप उस अन्य ऑब्जेक्ट की __new__ विधि का उपयोग कर सकते हैं। या यदि अन्य ऑब्जेक्ट पहले ही बनाया गया है, तो __call__ का उपयोग करने का प्रयास करें।

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