रूबी से अजगर सीखना; अंतर और समानताएँ


131

मैं रूबी को बहुत अच्छी तरह से जानता हूं। मुझे विश्वास है कि मुझे वर्तमान में पायथन सीखने की आवश्यकता हो सकती है। उन दोनों के लिए जो दोनों को जानते हैं, दोनों के बीच क्या अवधारणाएं समान हैं, और क्या अलग हैं?

मैं एक सूची के लिए देख रहा हूँ, जो मैंने लक्सर के लिए लक्सर के लिए लिखी एक प्राइमर के समान है : व्हाट्सएप महत्व और लूपिंग निर्माण जैसी सरल चीजें; nilअजगर का नाम , और किन मूल्यों को "सत्य" माना जाता है; यह के बराबर का उपयोग करने के मुहावरेदार है mapऔर each, या कर रहे हैं बुदबुदाना somethingaboutlistcomprehensions बुदबुदाना आदर्श?

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

संपादित करें : स्पष्ट होने के लिए, मेरा लक्ष्य "उचित" और मुहावरेदार पायथन है। अगर एक पायथन के बराबर है inject, लेकिन कोई भी इसका उपयोग नहीं करता है क्योंकि सूची को पुनरावृत्त करने और परिणाम के साथ संचय करने की सामान्य कार्यक्षमता को प्राप्त करने के लिए एक बेहतर / अलग तरीका है, मैं जानना चाहता हूं कि आप चीजों को कैसे करते हैं। शायद मैं इस सवाल को सामान्य लक्ष्यों की सूची के साथ अपडेट करूंगा कि आप उन्हें रूबी में कैसे हासिल करते हैं, और पूछें कि पायथन में समकक्ष क्या है।


1
केवल एक चीज जो मैंने पढ़ी, वह थी c2.com/cgi/wiki?PythonVsRuby , मैं वास्तव में स्वयं और अन्य लोगों की तरह नहीं हूं , लेकिन मुझे इसकी आदत है :)
सैफ अल हरथी

1
संबंधित: stackoverflow.com/questions/1113611/… (अगर यह एक डुप्लिकेट के बिना चीजों के लिए सवाल पूछता है तो मुझे यकीन नहीं है)।

19
@SilentGhost मैं दृढ़ता से असहमत हूँ। मैं पूछ रहा हूं कि "भाषाओं के बीच समान क्या है, और क्या अलग है?" जैसा कि नीचे दिए गए कई उत्तरों से पता चलता है, इसके लिए बहुत स्पष्ट और उपयोगी उत्तर संभव हैं।
फ्रॉग्ज

3
@Phrogz: मैं इसे देखता हूं और सवाल को गैर-जवाबदेह बनाता हूं।
साइलेंटगॉस्ट

2
@Pongongz - आपके द्वारा पोस्ट किए गए मेटा टॉपिक पर मैंने जो कहा है, उसे प्रतिध्वनित करने के लिए, इस प्रश्न के साथ समस्या यह है कि समस्या स्थान बहुत बड़ा है - यह केवल एक प्रश्न के लिए बहुत बड़ा विषय है। दोनों भाषाओं के बीच हजारों अंतर हैं।
एडम डेविस

जवाबों:


153

यहाँ मेरे लिए कुछ मुख्य अंतर हैं:

  1. रूबी में ब्लॉक हैं; अजगर नहीं करता है।

  2. पायथन के कार्य हैं; रूबी नहीं करती। पायथन में, आप किसी भी फ़ंक्शन या विधि को ले सकते हैं और इसे किसी अन्य फ़ंक्शन को पास कर सकते हैं। रूबी में, सब कुछ एक विधि है, और विधियों को सीधे पारित नहीं किया जा सकता है। इसके बजाय, आपको उन्हें पास करने के लिए प्रोक में लपेटना होगा।

  3. रूबी और पायथन दोनों बंद का समर्थन करते हैं, लेकिन अलग-अलग तरीकों से। पायथन में, आप एक फ़ंक्शन को दूसरे फ़ंक्शन के अंदर परिभाषित कर सकते हैं। आंतरिक फ़ंक्शन बाहरी फ़ंक्शन से चर तक पहुंच पढ़ता है, लेकिन पहुंच नहीं लिखता है। रूबी में, आप ब्लॉक का उपयोग करके बंद परिभाषित करते हैं। बाहरी दायरे से चरों की पहुंच पूरी तरह से है।

  4. पायथन में लिस्ट कॉम्प्रिहेंशन हैं, जो बहुत स्पष्ट हैं। उदाहरण के लिए, यदि आपके पास संख्याओं की सूची है, तो आप लिख सकते हैं

    [x*x for x in values if x > 15]

    15. से अधिक सभी मानों के वर्गों की एक नई सूची प्राप्त करने के लिए, रूबी में, आपको निम्नलिखित लिखना होगा:

    values.select {|v| v > 15}.map {|v| v * v}

    रूबी कोड कॉम्पैक्ट के रूप में महसूस नहीं करता है। यह भी उतना कुशल नहीं है क्योंकि यह पहले मान को सरणी को एक छोटे मध्यवर्ती सरणी में परिवर्तित करता है जिसमें मान 15. से अधिक होते हैं। फिर, यह मध्यवर्ती सरणी लेता है और मध्यवर्ती के वर्गों वाले एक अंतिम सरणी उत्पन्न करता है। मध्यवर्ती सरणी फिर बाहर फेंक दी जाती है। इसलिए, रूबी गणना के दौरान स्मृति में 3 सरणियों के साथ समाप्त होता है; अजगर को केवल इनपुट सूची और परिणामी सूची की आवश्यकता होती है।

    पायथन भी इसी तरह के मानचित्र समझ की आपूर्ति करता है।

  5. अजगर टुपल्स का समर्थन करता है; रूबी नहीं रूबी में, आपको ट्यूपल्स का अनुकरण करने के लिए सरणियों का उपयोग करना होगा।

  6. रूबी स्विच / केस स्टेटमेंट का समर्थन करती है; अजगर नहीं करता है।

  7. रूबी मानक expr ? val1 : val2टर्नरी ऑपरेटर का समर्थन करती है ; अजगर नहीं करता है।

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

  9. पायथन केवल सिंगल-लाइन लैम्बडा फ़ंक्शन का समर्थन करता है। रूबी ब्लॉक, जो कि प्रकार / लंबोदर फ़ंक्शन हैं, मनमाने ढंग से बड़े हो सकते हैं। इस वजह से, रूबी कोड आमतौर पर पायथन कोड की तुलना में अधिक कार्यात्मक शैली में लिखा गया है। उदाहरण के लिए, रूबी में एक सूची पर लूप करने के लिए, आप आमतौर पर करते हैं

    collection.each do |value|
      ...
    end

    ब्लॉक बहुत काम करता है जैसे एक फ़ंक्शन को पारित किया जा रहा है collection.each। यदि आप पायथन में एक ही काम करते हैं, तो आपको एक नामित आंतरिक फ़ंक्शन को परिभाषित करना होगा और फिर संग्रह को प्रत्येक विधि (यदि सूची ने इस विधि का समर्थन किया है) को पास करना होगा:

    def some_operation(value):
      ...
    
    collection.each(some_operation)

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

    for value in collection:
      ...
  10. संसाधनों का सुरक्षित तरीके से उपयोग करना दोनों भाषाओं के बीच काफी भिन्न है। यहां, समस्या यह है कि आप कुछ संसाधन आवंटित करना चाहते हैं (एक फ़ाइल खोलें, डेटाबेस कर्सर प्राप्त करें, आदि), उस पर कुछ मनमाना संचालन करें, और फिर अपवाद होने पर भी इसे सुरक्षित तरीके से बंद करें।

    रूबी में, क्योंकि ब्लॉक का उपयोग करना इतना आसान है (# 9 देखें), आप आमतौर पर इस पैटर्न को एक विधि के रूप में कोड करेंगे जो संसाधन पर मनमाने संचालन के लिए ब्लॉक लेता है।

    पायथन में, मनमाने ढंग से कार्रवाई के लिए एक समारोह में गुजरना थोड़ा अव्यवस्थित है क्योंकि आपको एक नामित, आंतरिक फ़ंक्शन (# 9 देखें) लिखना है। इसके बजाय, पायथन withसुरक्षित संसाधन हैंडलिंग के लिए एक बयान का उपयोग करता है । देखें कि मैं पायथन ऑब्जेक्ट को सही ढंग से कैसे साफ करूं? अधिक जानकारी के लिए।


2
3. पायथन 3 इसे nonlocalठीक करता है। पायथन आपको जेनरेटर एक्सप्रेशंस भी देता है (लिस्ट कॉम्प्रिहेंशन के समान, लेकिन पूछे जाने तक कुछ भी कंपेयर न करें - लिस्ट कॉम्प्रिहेंशन के बारे में सोचें क्योंकि जनरेटर एक्सप्रेशंस को फीड किया जाता है list(जो कि एक पुनरावृत्ति लेता है और सब कुछ के साथ लिस्ट लौटाता है) iterable यील्ड) - यह कुछ मामलों में बहुत प्रयास को बचा सकता है)।

25
7. हाँ यह करता है। val1 if expr else val2। 8. हालांकि मैं इसे ज्यादातर मिक्सिन-शैली में वृद्धि के लिए उपयोग करता हूं।

2
@ClintMiller वाह, कोई स्विच / मामला नहीं? तो, पायथन में समान कार्यक्षमता को प्राप्त करने का सुझाव दिया तरीका क्या है? यदि / बाकी / तो क्या होगा?
फ़िरोज़

15
# 4 में आपका माणिक उदाहरण मुहावरेदार नहीं है। लिखना अधिक रूबी-ईश (और पठनीय) होगा values.map{|v| v*v if v > 15}.compact। IMHO, यह आपके अजगर उदाहरण की तुलना में और भी अधिक अभिव्यंजक (और निश्चित रूप से स्पष्ट) है।
sml

10
उपरोक्त के अलावा, का उपयोग कर! कॉम्पैक्ट फ़ंक्शन का संस्करण सरणी की एक प्रति से बचा जाता है values.map{|v| v*v if v > 15}.compact!:। इसका मतलब यह है कि मेमोरी में केवल इनपुट सूची और परिणामी सूची मौजूद है। # 4 यहाँ देखें: igvita.com/2008/07/08/6-optimization-tips-for-ruby-mri
sml

27

मैंने अभी रूबी के 6 साल बाद अजगर को सीखने में कुछ महीने बिताए हैं। वहाँ वास्तव में दो भाषाओं के लिए कोई बड़ी तुलना नहीं थी, इसलिए मैंने खुद को लिखने और लिखने का फैसला किया। अब, यह है मुख्य रूप से कार्यात्मक प्रोग्रामिंग के साथ संबंध है, लेकिन जब से तुम रूबी के उल्लेख injectविधि, मेरा अनुमान है कि हम एक ही तरंग दैर्ध्य पर हैं।

मुझे आशा है कि यह मदद करता है: अजगर की 'कुरूपता'

कुछ बिंदु जो आपको सही दिशा में आगे बढ़ेंगे:

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

    def f(x):
        return x + 1
    
    map(f, [1, 2, 3]) # => [2, 3, 4]
  • अजगर के पास ऐसा कोई तरीका नहीं है जो काम करता हो each। चूंकि आप केवल eachसाइड इफेक्ट्स के लिए उपयोग करते हैं, पाइथन में समकक्ष लूप के लिए है:

    for n in [1, 2, 3]:
        print n
  • सूची बोध तब बहुत अच्छा होता है जब क) आपको फ़ंक्शन और ऑब्जेक्ट संग्रह को एक साथ और बी से निपटना पड़ता है) जब आपको कई अनुक्रमित का उपयोग करने की आवश्यकता होती है। उदाहरण के लिए, सभी पैलिंड्रोमों को एक स्ट्रिंग में खोजने के लिए (यह मानकर कि आपके पास एक फ़ंक्शन है p()जो पैलिंड्रोम्स के लिए सही है), आपको केवल एक सूची की समझ की आवश्यकता है:

    s = 'string-with-palindromes-like-abbalabba'
    l = len(s)
    [s[x:y] for x in range(l) for y in range(x,l+1) if p(s[x:y])]

3
आह, मैंने उस पोस्ट को पढ़ा और यह मेरे संदेह की पुष्टि करता है: कुछ लोग पायथन में विशेष विधियों की भूमिका और उपयोगिता को समझते हैं। वे अविश्वसनीय रूप से उपयोगी और मानकीकृत हैं, और वे इस तरह अंडरस्क्राइब किए गए हैं ताकि उन बिल्डरों के साथ नामकरण संघर्ष से बचने के लिए जिन्हें वे अक्सर लागू करते हैं। कोई भी जो वास्तव में पायथन को नहीं जानता है, उनके उपयोग को हतोत्साहित करने की कोशिश कर रहा है।
राफे केटलर

5
आपको समझ में नहीं आता है कि कैसे तरीके काम करते हैं। एक विधि, अनिवार्य रूप से, एक फ़ंक्शन है जिसका पहला तर्क उस वर्ग का एक उदाहरण है जो विधि से संबंधित है। जब आप लिखते हैं Class.method, तो विधि "अनबाउंड" है और पहला तर्क एक Classउदाहरण होना चाहिए ; जब आप लिखते हैं object.method, तो विधि objectउदाहरण के लिए "बाध्य" है Class। इससे आप यह चुन सकते हैं कि हर बार एक अंतर उदाहरण पर विधि को कॉल करने के लिए मानचित्र (आदि) का उपयोग करें (एक अनबाउंड विधि पास करें), या उदाहरण को स्थिर रखने के लिए और हर बार एक अलग दूसरा तर्क पारित करें। दोनों उपयोगी हैं।
लाक

2
आप सही हैं, मुझे समझ नहीं आया कि उन्होंने कैसे काम किया। लेख प्रकाशित करने के बाद से, मैंने इसके लिए एक बेहतर अर्थ प्राप्त कर लिया है। धन्यवाद!
डेविड जे।

10
[s[x:y] for x in range(l) for y in range(x,l+1) if p(s[x:y])]- यह पंक्ति बताती है कि पायथन पढ़ना कितना कठिन है। जब आप रूबी कोड पढ़ते हैं तो आप अपनी आंखों को बाएं से दाएं, बिना किसी रिटर्न के घुमाते हैं। लेकिन पायथन कोड को पढ़ने के लिए, आपको बाएं-दाएं-बाएं-दाएं-बाएं-दाएं जाने की आवश्यकता होती है ... और कोष्ठक, कोष्ठक, कोष्ठक, कोष्ठक ... पायथन में भी आपको अक्सर विधियों और कार्यों के मिश्रण की आवश्यकता होती है। यह पागलपन है: E(C(A.B()).D())रूबी के बजायA.B.C.D.E
नाकीलोन

2
@Nakilon यही कारण है कि आपको वास्तव में सरल मामलों के लिए केवल नेस्टेड सूची समझ का उपयोग करना चाहिए, और उपरोक्त की तरह नहीं। एक लाइनर को लिखने के लिए यह 'चतुर' हो सकता है जो एक स्ट्रिंग में सभी पैलिंड्रोम्स पाता है, लेकिन यह कोड गोल्फ के लिए सबसे अच्छा आरक्षित है। वास्तविक कोड के लिए जिसे किसी और को बाद में पढ़ना है, आप बस कुछ लाइन फ़ंक्शन लिखेंगे। तो हाँ, यह पंक्ति पढ़ना कठिन है, लेकिन यह प्रोग्रामर की गलती है, भाषा की नहीं।
कैम जैक्सन

10

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

अब, उस कहावत के साथ, अंतर आपको तेजी से अनुकूल बनाने और पायथन कार्यक्रम में 1 संशोधन करने में मदद करेगा। और लेखन शुरू करने के लिए यह ठीक है। लेकिन अन्य परियोजनाओं से सीखने की कोशिश करें कि भाषा के शब्दार्थ के बजाय वास्तुकला और डिजाइन के फैसले के पीछे क्यों ...


7
मैं आपके सुझाव की सराहना करता हूं। मैं पूरी तरह से भावुकता से सहमत हूं (जिसे मैं "मुहावरेदार कार्यक्रम सीखना सीखता हूं") । ठीक यही मैं करने की कोशिश कर रहा हूं। मैं नहीं पूछ रहा हूं "रूबी की eachविधि के लिए पायथन नाम क्या है ?" मैं पूछ रहा हूं "रूबी से अलग पायथन में चीजें कैसे ठीक से की जाती हैं, और वे ठीक से कहां की जाती हैं?" अगर पायथन falseवास्तव में है False, तो यह जानना उतना ही महत्वपूर्ण है कि मुझे रूबेक तरीके से कहां और कब करना चाहिए, और कहां और कब नहीं करना चाहिए।
फ्रोग्ज़

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

मैं एक ही समय में अजगर और रूबी सीख रहा हूं, और वेब ऐप देव में मुझे अंतर से अधिक समानताएं दिखाई देती हैं।
पश्चिमीगुन

8

मैं रूबी को बहुत कम जानता हूं, लेकिन यहां आपके द्वारा बताई गई चीजों के बारे में कुछ बुलेट बिंदु हैं:

  • nilमान की कमी का संकेत देने वाला मूल्य, होगा None(ध्यान दें कि आप इसके लिए जांच करते हैं x is Noneया जैसे x is not None, नहीं ==- या बूलियन के लिए जबरदस्ती द्वारा, अगले बिंदु देखें)।
  • None, शून्य-esque संख्या ( 0, 0.0, 0j(जटिल संख्या)) और खाली संग्रह ( [], {}, set(), खाली स्ट्रिंग "", आदि) falsy, बाकी सब माना जाता है truthy माना जाता है।
  • साइड इफेक्ट्स के लिए, ( for-) स्पष्ट रूप से लूप। साइड-इफेक्ट्स के बिना सामान का एक नया गुच्छा बनाने के लिए, सूची संकलन (या उनके रिश्तेदारों - आलसी एक बार पुनरावृत्तियों के लिए जनरेटर के भाव, उक्त संग्रहों के लिए तानाशाह / सेट समझ) का उपयोग करें।

लूपिंग के बारे में: आपके पास for, जो एक चलने योग्य (और कोई गिनती नहीं) पर संचालित होता है, और while, जो वह करता है जो आप उम्मीद करेंगे। इससे चलने वाला कहीं अधिक शक्तिशाली है, पुनरावृत्तियों के व्यापक समर्थन के लिए धन्यवाद। न केवल लगभग हर चीज जो एक सूची के बजाय एक पुनरावृत्ति हो सकती है, एक पुनरावृत्ति है (कम से कम पायथन 3 में - पायथन 2 में, आपके पास दोनों हैं और डिफ़ॉल्ट एक सूची है, दुख की बात है)। zipपुनरावृत्तियों के साथ काम करने के लिए कई उपकरण हैं - समानांतर में किसी भी संख्या में पुनरावृत्तियों को पुनरावृत्त करता है, enumerateआपको (index, item)( किसी भी iterable पर, न कि केवल सूचियों पर) देता है, यहां तक ​​कि तिरछी (संभवतः बड़ी या अनंत) पुनरावृत्तियों को भी काटता है! मैंने पाया कि ये बहुत सारे लूपिंग कार्यों को बहुत सरल बनाते हैं। कहने की जरूरत नहीं है, वे सूची समझ, जनरेटर अभिव्यक्ति आदि के साथ ठीक ठीक एकीकृत करते हैं।


2
जेनरेटर के भाव शांत हैं। वे पायथन को हस्केल जैसी भाषाओं की आलसी मूल्यांकन क्षमताओं का एक सा देते हैं।
क्लिंट मिलर

@ क्लिंट: हाँ। और पूर्ण जनरेटर और भी अधिक सक्षम हैं (हालांकि साधारण मामलों के लिए आवश्यक नहीं है, जो कि बहुसंख्यक होते हैं)।

आप के साथ जाँच क्यों x is Noneया x is not None? मैं हमेशा x == Noneऔर के साथ की जाँच करें x != None
जॉन

@ जॉन: यदि एक मूर्खतापूर्ण तरीके से xपरिभाषित __eq__किया जाता है, तो यह एक झूठी सकारात्मक दे सकता है। यदि __eq__सावधानीपूर्वक पर्याप्त रूप से प्रोग्राम नहीं किया गया है, तो AttributeErrorकुछ मान (यानी None) दिए जाने पर यह दुर्घटनाग्रस्त हो सकता है (जैसे )। इसके विपरीत, isओवरराइड नहीं किया जा सकता है - यह हमेशा ऑब्जेक्ट आइडेंटिटी की तुलना करता है, जो कि सिंगलटन की जांच करने का सही (सबसे मजबूत, सरल और सबसे साफ) तरीका है।

1
@ जॉन। "x कोई नहीं" यह करने के लिए बिल्कुल मुहावरेदार तरीका है। python.net/~goodger/projects/pycon/2007/idiomatic/handout.html
tokland

6

रूबी में, उदाहरण के चर और तरीके पूरी तरह से असंबंधित हैं, सिवाय इसके कि जब आप स्पष्ट रूप से उन्हें attr_accessor या ऐसा कुछ के साथ संबंधित करते हैं।

पायथन में, विधियां केवल विशेषता का एक विशेष वर्ग हैं: एक जो निष्पादन योग्य है।

उदाहरण के लिए:

>>> class foo:
...     x = 5
...     def y(): pass
... 
>>> f = foo()
>>> type(f.x)
<type 'int'>
>>> type(f.y)
<type 'instancemethod'>

उस अंतर के बहुत सारे निहितार्थ हैं, जैसे उदाहरण के लिए कि एफएक्स का संदर्भ विधि ऑब्जेक्ट को संदर्भित करता है, बजाय इसे कॉल करने के। इसके अलावा, जैसा कि आप देख सकते हैं, एफएक्स डिफ़ॉल्ट रूप से सार्वजनिक है, जबकि रूबी में, उदाहरण चर डिफ़ॉल्ट रूप से निजी हैं।


2
वास्तव में, मैं इसे और भी अधिक स्पष्ट रूप से बताऊंगा: पायथन में, विधियाँ एक विशेष प्रकार की विशेषता है, जबकि रूबी में, विशेषताएँ केवल एक विशेष प्रकार की विधि हैं। अजगर में प्रथम श्रेणी कार्य, और रूबी में वर्दी पहुँच सिद्धांत: दो भाषाओं के बीच कुछ महत्वपूर्ण विषम सुविधाओं को इस से बाहर हो जाते
philomory
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.