python - आप पायथन में एकाधिक मान कैसे वापस करते हैं?




coding-style return (9)

आम तौर पर, "विशेष संरचना" वास्तव में अपने स्वयं के तरीकों के साथ एक वस्तु की एक समझदार वर्तमान स्थिति है।

class Some3SpaceThing(object):
  def __init__(self,x):
    self.g(x)
  def g(self,x):
    self.y0 = x + 1
    self.y1 = x * 3
    self.y2 = y0 ** y3

r = Some3SpaceThing( x )
r.y0
r.y1
r.y2

जहां संभव हो वहां अज्ञात संरचनाओं के लिए नाम ढूंढना पसंद है। अर्थपूर्ण नाम चीजों को और स्पष्ट करते हैं।

इसका समर्थन करने वाली भाषाओं में कई मानों को वापस करने का वैचारिक तरीका प्रायः tupling

विकल्प: एक ट्यूपल का उपयोग करना

इस मामूली उदाहरण पर विचार करें:

def f(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return (y0,y1,y2)

हालांकि, यह जल्दी से समस्याग्रस्त हो जाता है क्योंकि मूल्यों की संख्या में वृद्धि हुई है। क्या होगा यदि आप चार या पांच मूल्य वापस करना चाहते हैं? निश्चित रूप से, आप उन्हें टपलिंग कर सकते हैं, लेकिन यह भूलना आसान हो जाता है कि कौन सा मूल्य है। जहां भी आप उन्हें प्राप्त करना चाहते हैं, उन्हें अनपॅक करने के लिए भी बदसूरत है।

विकल्प: एक शब्दकोश का प्रयोग करना

ऐसा लगता है कि अगला तार्किक कदम कुछ प्रकार के 'रिकॉर्ड नोटेशन' पेश करना प्रतीत होता है। पायथन में, ऐसा करने का स्पष्ट तरीका एक dict माध्यम से होता है।

निम्नलिखित को धयान मे रखते हुए:

def g(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return {'y0':y0, 'y1':y1 ,'y2':y2 }

(संपादित करें- बस स्पष्ट होने के लिए, y0, y1 और y2 केवल सार पहचानकर्ताओं के रूप में हैं। जैसा कि बताया गया है, अभ्यास में आप सार्थक पहचानकर्ताओं का उपयोग करेंगे)

अब, हमारे पास एक तंत्र है जिससे हम लौटे ऑब्जेक्ट के किसी विशेष सदस्य को पेश कर सकते हैं। उदाहरण के लिए,

result['y0']

विकल्प: एक वर्ग का उपयोग करना

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

class ReturnValue(object):
  def __init__(self, y0, y1, y2):
     self.y0 = y0
     self.y1 = y1
     self.y2 = y2

def g(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return ReturnValue(y0, y1, y2)

पाइथन में पिछले दो शायद नलसाजी के मामले में बहुत समान हैं- सभी { y0, y1, y2 } बाद __dict__ के आंतरिक __dict__ में प्रविष्टियां होने ReturnValue

पाइथन द्वारा प्रदान की गई एक अतिरिक्त सुविधा है हालांकि छोटी वस्तुओं के लिए, __slots__ विशेषता। कक्षा को इस प्रकार व्यक्त किया जा सकता है:

class ReturnValue(object):
  __slots__ = ["y0", "y1", "y2"]
  def __init__(self, y0, y1, y2):
     self.y0 = y0
     self.y1 = y1
     self.y2 = y2

पायथन संदर्भ मैनुअल से :

__slots__ घोषणा उदाहरण चर के अनुक्रम लेती है और प्रत्येक आवृत्ति के लिए मान रखने के लिए प्रत्येक उदाहरण में पर्याप्त स्थान सुरक्षित रखती है। अंतरिक्ष सहेजा गया है क्योंकि प्रत्येक उदाहरण के लिए __dict__ नहीं बनाया गया है।

विकल्प: एक सूची का उपयोग करना

एक अन्य सुझाव जिसे मैंने अनदेखा किया बिल बिल लizard से आता है:

def h(x):
  result = [x + 1]
  result.append(x * 3)
  result.append(y0 ** y3)
  return result

यद्यपि यह मेरी सबसे पसंदीदा विधि है। मुझे लगता है कि मैं हास्केल के संपर्क में दब गया हूं, लेकिन मिश्रित प्रकार की सूचियों का विचार हमेशा मुझे असहज महसूस करता है। इस विशेष उदाहरण में सूची-मिश्रित प्रकार नहीं है, लेकिन यह अनुमानतः हो सकता है। जहां तक ​​मैं कह सकता हूं, इस तरह से उपयोग की जाने वाली सूची वास्तव में टुपल के संबंध में कुछ भी नहीं प्राप्त करती है। पाइथन में सूचियों और टुपल्स के बीच एकमात्र असली अंतर यह है कि सूचियां mutable , वेरास टुपल्स नहीं हैं। मैं व्यक्तिगत रूप से कार्यात्मक प्रोग्रामिंग से सम्मेलनों को ले जाता हूं: उसी प्रकार के तत्वों के किसी भी संख्या के लिए सूचियों का उपयोग करें, और पूर्व निर्धारित प्रकार के तत्वों की निश्चित संख्या के लिए टुपल्स का उपयोग करें।

सवाल

लंबी प्रस्तुति के बाद, अनिवार्य सवाल आता है। कौन सी विधि (आपको लगता है) सबसे अच्छा है?

मैंने आमतौर पर खुद को शब्दकोश मार्ग पर जाना पाया है क्योंकि इसमें कम सेट-अप कार्य शामिल है। हालांकि, एक प्रकार के परिप्रेक्ष्य से, आप कक्षा मार्ग पर जाने से बेहतर हो सकते हैं, क्योंकि यह आपको एक शब्दकोश का प्रतिनिधित्व करने में भ्रमित होने से बचने में मदद कर सकता है। दूसरी तरफ, पाइथन समुदाय में कुछ ऐसे हैं जो महसूस करते हैं कि अंतर्निहित इंटरफेस को स्पष्ट इंटरफेस के लिए प्राथमिकता दी जानी चाहिए , जिस बिंदु पर वस्तु का प्रकार वास्तव में प्रासंगिक नहीं है, क्योंकि आप मूल रूप से इस सम्मेलन पर निर्भर हैं कि वही विशेषता हमेशा एक ही अर्थ होगा।

तो, पायथन में कई मूल्यों को कैसे करें?


इस उद्देश्य के लिए नामांकित tuples 2.6 में जोड़ा गया था। इसी तरह के अंतर्निहित उदाहरण के लिए os.stat भी देखें।

>>> import collections
>>> Point = collections.namedtuple('Point', ['x', 'y'])
>>> p = Point(1, y=2)
>>> p.x, p.y
1 2
>>> p[0], p[1]
1 2

कई उत्तरों का सुझाव है कि आपको किसी प्रकार का संग्रह, एक शब्दकोश या सूची की तरह वापस करने की आवश्यकता है। आप अतिरिक्त वाक्यविन्यास छोड़ सकते हैं और केवल वापसी मान, अल्पविराम से अलग लिख सकते हैं। नोट: यह तकनीकी रूप से एक ट्यूपल देता है।

def f():
    return True, False
x, y = f()
print(x)
print(y)

देता है:

True
False

छोटी परियोजनाओं के लिए मुझे टुपल्स के साथ काम करना सबसे आसान लगता है। जब इसे प्रबंधित करने में बहुत मुश्किल हो जाती है (और पहले नहीं) मैं तार्किक संरचनाओं में चीजों को समूहीकृत करना शुरू करता हूं, हालांकि मुझे लगता है कि आपके सुझाए गए उपयोग और रिटर्नवैल्यू ऑब्जेक्ट्स का गलत उपयोग गलत है (या बहुत सरल)।

कुंजी y0, y1, y2 आदि के साथ एक शब्दकोश लौटने से टुपल्स पर कोई लाभ नहीं मिलता है। गुणों के साथ रिटर्नवैल्यू इंस्टेंस लौटाना .y0 .y1 .y2 आदि tuples पर किसी भी लाभ की पेशकश नहीं करता है। यदि आप कहीं भी जाना चाहते हैं तो आपको चीजों का नाम देना शुरू करना होगा, और आप वैसे भी टुपल्स का उपयोग कर ऐसा कर सकते हैं:

def getImageData(filename):
  [snip]
  return size, (format, version, compression), (width,height)
size, type, dimensions = getImageData(x)

re.match() , re.match() से परे एकमात्र अच्छी तकनीक वास्तविक वस्तुओं और गुणों के साथ वास्तविक वस्तुओं को वापस करना है, जैसे कि आप re.match() या open(file)


जेनरेटर का उपयोग करने का एक और विकल्प होगा:

>>> def f(x):
        y0 = x + 1
        yield y0
        yield x * 3
        yield y0 ** 4


>>> a, b, c = f(5)
>>> a
6
>>> b
15
>>> c
1296

यद्यपि आईएमएचओ टुपल्स आमतौर पर सबसे अच्छे होते हैं, ऐसे मामलों को छोड़कर जहां मूल्य लौटाया जा रहा है, वे कक्षा में encapsulation के लिए उम्मीदवार हैं।


पायथन के tuples, dicts, और वस्तुओं प्रोग्रामर छोटे आकार संरचनाओं ("चीजें") के लिए औपचारिकता और सुविधा के बीच एक चिकनी व्यापार समझौता प्रदान करते हैं। मेरे लिए, किसी चीज का प्रतिनिधित्व करने का विकल्प मुख्य रूप से निर्धारित करता है कि मैं संरचना का उपयोग कैसे कर रहा हूं। सी ++ में, विधियों के साथ वस्तुओं के लिए डेटा-केवल वस्तुओं और class लिए struct का उपयोग करने के लिए यह एक आम सम्मेलन है, भले ही आप कानूनी रूप से struct पर विधियां डाल सकें; मेरी आदत पाइथन में समान है, जिसमें struct स्थान पर dict और tuple है।

समन्वय सेट के लिए, मैं एक बिंदु class या एक dict बजाय एक tuple उपयोग करेंगे (और ध्यान दें कि आप एक शब्दकोश कुंजी के रूप में एक tuple उपयोग कर सकते हैं, तो dict एस महान मल्टी multimimensional सरणी बनाते हैं)।

अगर मैं चीजों की सूची में पुनरावृत्ति करने जा रहा हूं, तो मैं पुनरावृत्ति पर अनपॅकिंग tuple पसंद करता हूं:

for score,id,name in scoreAllTheThings():
    if score > goodScoreThreshold:
        print "%6.3f #%6d %s"%(score,id,name)

... जैसा ऑब्जेक्ट संस्करण पढ़ने के लिए अधिक अव्यवस्थित है:

for entry in scoreAllTheThings():
    if entry.score > goodScoreThreshold:
        print "%6.3f #%6d %s"%(entry.score,entry.id,entry.name)

... अकेले ही निर्देश दें।

for entry in scoreAllTheThings():
    if entry['score'] > goodScoreThreshold:
        print "%6.3f #%6d %s"%(entry['score'],entry['id'],entry['name'])

यदि चीज का व्यापक रूप से उपयोग किया जाता है, और आप कोड में कई स्थानों पर अपने आप को समान गैर-तुच्छ संचालन करते हैं, तो यह उचित तरीके से कक्षा वस्तु बनाने के लिए आमतौर पर उपयुक्त है।

अंत में, यदि मैं गैर-पायथन सिस्टम घटकों के साथ डेटा का आदान-प्रदान करने जा रहा हूं, तो मैं अक्सर उन्हें एक dict में dict क्योंकि यह जेएसओएन क्रमबद्धता के लिए सबसे उपयुक्त है।


मैं एक समारोह से मूल्यों को पारित करने और वापस करने के लिए एक नियम का उपयोग करता हूं:

फॉर्म में परिभाषित वैरिएबल फॉर्म का प्रयोग करें।

form = {
    'level': 0,
    'points': 0,
    'game': {
        'name': ''
    }
}


def test(form):
    form['game']['name'] = 'My game!'
    form['level'] = 2

    return form

>>> print(test(form))
{u'game': {u'name': u'My game!'}, u'points': 0, u'level': 2}

यह मेरे लिए और प्रसंस्करण इकाई के लिए सबसे प्रभावी तरीका है।

आपको केवल एक पॉइंटर पास करना होगा और केवल एक पॉइंटर आउट करना होगा।

जब भी आप अपने कोड में बदलाव करते हैं तो आपको फ़ंक्शंस '(उनमें से हजारों) तर्कों को बदलने की ज़रूरत नहीं है।


मैं पसंद करता हूं

def g(x):
  y0 = x + 1
  y1 = x * 3
  y2 = y0 ** y3
  return {'y0':y0, 'y1':y1 ,'y2':y2 }

ऐसा लगता है कि सब कुछ एक ही काम करने के लिए सिर्फ अतिरिक्त कोड है।


>>> def func():
...    return [1,2,3]
...
>>> a,b,c = func()
>>> a
1
>>> b
2
>>> c
3






return-value