python - पायथन में वृद्धि और कमी ऑपरेटर का व्यवहार




operators increment (4)

मैंने देखा है कि पूर्व-वृद्धि / कमी ऑपरेटर को एक चर (जैसे ++count ) पर लागू किया जा सकता है। यह संकलित करता है, लेकिन यह वास्तव में चर के मान को नहीं बदलता है!

पायथन में पूर्व-वृद्धि / कमी ऑपरेटर (++ / -) का व्यवहार क्या है?

सी / सी ++ में देखे गए इन ऑपरेटरों के व्यवहार से पाइथन क्यों विचलित हो जाते हैं?


पाइथन में, सामान्य लिस्प, योजना, या रूबी जैसी भाषाओं के विपरीत अभिव्यक्तियों और बयानों के बीच एक भेद कठोर रूप से लागू होता है।

Wikipedia

तो ऐसे ऑपरेटरों को पेश करके, आप अभिव्यक्ति / कथन विभाजित तोड़ देंगे।

इसी कारण से आप लिख नहीं सकते हैं

if x = 0:
  y = 1

जैसा कि आप कुछ अन्य भाषाओं में कर सकते हैं जहां इस तरह का भेद संरक्षित नहीं है।


जब आप वृद्धि या कमी करना चाहते हैं, तो आप आमतौर पर इसे पूर्णांक पर करना चाहते हैं। इस तरह:

b++

लेकिन पायथन में, पूर्णांक अपरिवर्तनीय हैं । यही है कि आप उन्हें बदल नहीं सकते हैं। ऐसा इसलिए है क्योंकि पूर्णांक वस्तुओं का उपयोग कई नामों के तहत किया जा सकता है। इसे इस्तेमाल करे:

>>> b = 5
>>> a = 5
>>> id(a)
162334512
>>> id(b)
162334512
>>> a is b
True

उपरोक्त ए और बी वास्तव में एक ही वस्तु हैं। यदि आप एक वृद्धि हुई है, तो आप भी बी वृद्धि होगी। यह वही नहीं है जो आप चाहते हैं। तो आपको फिर से सौंपना होगा। इस कदर:

b = b + 1

या सरल:

b += 1

b b+1 को फिर से सौंपेगा। यह एक वृद्धि ऑपरेटर नहीं है, क्योंकि यह b वृद्धि नहीं करता है, यह इसे फिर से सौंपता है।

संक्षेप में: पायथन अलग-अलग व्यवहार करता है, क्योंकि यह सी नहीं है, और मशीन कोड के चारों ओर एक निम्न स्तर का रैपर नहीं है, लेकिन एक उच्च स्तरीय गतिशील भाषा है, जहां वृद्धि में कोई अर्थ नहीं है, और सी में भी आवश्यक नहीं है , उदाहरण के लिए, जब भी आप लूप रखते हैं, तो आप उनका उपयोग करते हैं।


पाइथन में इन ऑपरेटरों नहीं हैं, लेकिन यदि आपको वास्तव में उनकी आवश्यकता है तो आप एक ही कार्यक्षमता वाले फ़ंक्शन को लिख सकते हैं।

def PreIncrement(name, local={}):
    #Equivalent to ++name
    if name in local:
        local[name]+=1
        return local[name]
    globals()[name]+=1
    return globals()[name]

def PostIncrement(name, local={}):
    #Equivalent to name++
    if name in local:
        local[name]+=1
        return local[name]-1
    globals()[name]+=1
    return globals()[name]-1

उपयोग:

x = 1
y = PreIncrement('x') #y and x are both 2
a = 1
b = PostIncrement('a') #b is 1 and a is 2

यदि आप स्थानीय चर बदलना चाहते हैं तो एक फ़ंक्शन के अंदर आपको स्थानीय तर्क () को दूसरे तर्क के रूप में जोड़ना होगा, अन्यथा यह वैश्विक को बदलने का प्रयास करेगा।

x = 1
def test():
    x = 10
    y = PreIncrement('x') #y will be 2, local x will be still 10 and global x will be changed to 2
    z = PreIncrement('x', locals()) #z will be 11, local x will be 11 and global x will be unaltered
test()

इन कार्यों के साथ आप कर सकते हैं:

x = 1
print(PreIncrement('x'))   #print(x+=1) is illegal!

लेकिन मेरी राय में निम्नलिखित दृष्टिकोण स्पष्ट है:

x = 1
x+=1
print(x)

विघटन ऑपरेटर:

def PreDecrement(name, local={}):
    #Equivalent to --name
    if name in local:
        local[name]-=1
        return local[name]
    globals()[name]-=1
    return globals()[name]

def PostDecrement(name, local={}):
    #Equivalent to name--
    if name in local:
        local[name]-=1
        return local[name]+1
    globals()[name]-=1
    return globals()[name]+1

मैंने अपने मॉड्यूल में इन कार्यों का उपयोग जावास्क्रिप्ट को पायथन में अनुवादित किया था।


हाँ, मैं ++ और कार्यक्षमता भी चूक गया। सी कोड की कुछ मिलियन लाइनों ने मेरे पुराने सिर में उस तरह की सोच को जन्म दिया, और इसे लड़ने के बजाय ... यहां एक वर्ग है जिसे मैंने लागू किया है:

pre- and post-increment, pre- and post-decrement, addition,
subtraction, multiplication, division, results assignable
as integer, printable, settable.

यहाँ 'टीआईएस:

class counter(object):
    def __init__(self,v=0):
        self.set(v)

    def preinc(self):
        self.v += 1
        return self.v
    def predec(self):
        self.v -= 1
        return self.v

    def postinc(self):
        self.v += 1
        return self.v - 1
    def postdec(self):
        self.v -= 1
        return self.v + 1

    def __add__(self,addend):
        return self.v + addend
    def __sub__(self,subtrahend):
        return self.v - subtrahend
    def __mul__(self,multiplier):
        return self.v * multiplier
    def __div__(self,divisor):
        return self.v / divisor

    def __getitem__(self):
        return self.v

    def __str__(self):
        return str(self.v)

    def set(self,v):
        if type(v) != int:
            v = 0
        self.v = v

आप इसका इस्तेमाल इस तरह कर सकते हैं:

c = counter()                          # defaults to zero
for listItem in myList:                # imaginary task
     doSomething(c.postinc(),listItem) # passes c, but becomes c+1

... पहले से ही सी है, आप यह कर सकते हैं ...

c.set(11)
while c.predec() > 0:
    print c

....या केवल...

d = counter(11)
while d.predec() > 0:
    print d

... और (पुन:) पूर्णांक में असाइनमेंट के लिए ...

c = counter(100)
d = c + 223 # assignment as integer
c = c + 223 # re-assignment as integer
print type(c),c # <type 'int'> 323

... जबकि यह टाइप काउंटर के रूप में सी बनाए रखेगा:

c = counter(100)
c.set(c + 223)
print type(c),c # <class '__main__.counter'> 323

संपादित करें:

और फिर यह अप्रत्याशित (और पूरी तरह से अवांछित) व्यवहार का थोड़ा सा है ,

c = counter(42)
s = '%s: %d' % ('Expecting 42',c) # but getting non-numeric exception
print s

... क्योंकि उस tuple के अंदर, getitem () का उपयोग नहीं किया जाता है, इसके बजाय ऑब्जेक्ट का संदर्भ फ़ॉर्मेटिंग फ़ंक्शन पर पास किया जाता है। आह। इसलिए:

c = counter(42)
s = '%s: %d' % ('Expecting 42',c.v) # and getting 42.
print s

... या, अधिक verbosely, और स्पष्ट रूप से हम वास्तव में क्या करना चाहता था, हालांकि verbosity द्वारा वास्तविक रूप में काउंटर-संकेत (इसके बजाय cv उपयोग करें) ...

c = counter(42)
s = '%s: %d' % ('Expecting 42',c.__getitem__()) # and getting 42.
print s




decrement