अजगर में परिपत्र (या चक्रीय) आयात करता है


353

यदि दो मॉड्यूल एक दूसरे को आयात करते हैं तो क्या होगा?

समस्या को सामान्य करने के लिए, अजगर में चक्रीय आयात के बारे में क्या?



1
यह भी एक संदर्भ के रूप में, ऐसा लगता है कि अजगर 3.5 (और शायद परे) पर परिपत्र आयात की अनुमति है, लेकिन 3.4 नहीं (और शायद bellow)।
चार्ली पार्कर

4
मैं अजगर 3.7.2 का उपयोग कर रहा हूं और अभी भी परिपत्र निर्भरता के कारण रनटाइम त्रुटि हो रही है।
रिचर्ड व्हाइटहेड

जवाबों:


282

पिछले साल comp.lang.python में इस पर बहुत अच्छी चर्चा हुई थी। यह आपके प्रश्न का बहुत अच्छी तरह से उत्तर देता है।

आयात बहुत सीधे हैं। बस निम्नलिखित याद रखें:

'आयात' और 'xxx आयात yyy' से निष्पादन योग्य कथन हैं। जब रनिंग प्रोग्राम उस लाइन तक पहुंचता है तो वे निष्पादित करते हैं।

यदि कोई मॉड्यूल sys.modules में नहीं है, तो एक आयात sys.modules में नए मॉड्यूल प्रविष्टि बनाता है और फिर मॉड्यूल में कोड निष्पादित करता है। निष्पादन पूरा होने तक यह कॉलिंग मॉड्यूल पर नियंत्रण वापस नहीं करता है।

यदि कोई मॉड्यूल sys.modules में मौजूद है, तो एक आयात बस उस मॉड्यूल को लौटाता है, चाहे उसने निष्पादन को पूरा किया हो या नहीं। यही कारण है कि चक्रीय आयात मॉड्यूल लौटा सकते हैं जो आंशिक रूप से खाली दिखाई देते हैं।

अंत में, निष्पादित स्क्रिप्ट __main__ नाम के एक मॉड्यूल में चलती है, स्क्रिप्ट को अपने नाम से आयात करने से __main__ से असंबंधित एक नया मॉड्यूल बन जाएगा।

मॉड्यूल आयात करते समय आपको बहुत कुछ लेना चाहिए और आपको कोई आश्चर्य नहीं होना चाहिए।


13
@meawoppl क्या आप इस टिप्पणी का विस्तार कर सकते हैं, कृपया? वे विशेष रूप से कैसे बदल गए हैं?
डैन शिएन

3
अब तक, python3 में परिपत्र आयात का एकमात्र संदर्भ "नया क्या है?" पेज 3.5 में हैं । इसमें कहा गया है कि "रिश्तेदार आयात से जुड़े सर्कुलर आयात अब समर्थित हैं"। @meawoppl क्या आपने कुछ और पाया है जो इन पृष्ठों में सूचीबद्ध नहीं है?
zezollo

4
वे पराजित हैं। 3.0-3.4 में समर्थित नहीं है। या कम से कम सफलता के लिए शब्दार्थ अलग हैं। यहाँ एक सारांश है मैंने पाया कि 3.5 परिवर्तनों का उल्लेख नहीं किया है। gist.github.com/datagrok/40bf84d5870c41a77dc6
meawoppl

कृपया आप इस पर विस्तार कर सकते हैं "अंत में, निष्पादित स्क्रिप्ट मुख्य नाम के मॉड्यूल में चलती है , स्क्रिप्ट को अपने नाम से आयात करने से मुख्य से असंबंधित एक नया मॉड्यूल तैयार होगा ।" तो मान लें कि फ़ाइल एक थिंकपैड है और जब यह मुख्य प्रविष्टि बिंदु के रूप में चलता है, तो इसका मुख्य अब अगर यह कुछ चर से आयात की तरह कोड है। फिर क्या वही फाइल 'थिंकपैड' sys मॉड्यूल टेबल में लोड हो जाएगी? तो क्या इसका मतलब यह है कि अगर उसने प्रिंट स्टेटमेंट कहा है तो वह दो बार चलेगा? एक बार मुख्य फ़ाइल के लिए और फिर से जब आयात का सामना करना पड़ता है?
चर

यह उत्तर 10 साल पुराना है, और मैं यह सुनिश्चित करने के लिए एक आधुनिकीकरण अद्यतन चाहूंगा कि यह पायथन, 2.x या 3.x के विभिन्न संस्करणों में सही बना रहे
फॉलेंप्रिपर

296

यदि आप import fooअंदर barऔर import barअंदर करते हैं foo, तो यह ठीक काम करेगा। जब तक वास्तव में कुछ भी चलता है, तब तक दोनों मॉड्यूल पूरी तरह से लोड हो जाएंगे और एक दूसरे के संदर्भ होंगे।

समस्या यह है कि जब आप करते हैं from foo import abcऔर इसके बजाय from bar import xyz। क्योंकि अब प्रत्येक मॉड्यूल को आयात करने से पहले दूसरे मॉड्यूल को पहले से ही आयात करने की आवश्यकता होती है (ताकि हम जो नाम आयात कर रहे हैं वह मौजूद हो)।


27
ऐसा लगता है कि from foo import *और from bar import *यह भी ठीक काम करेगा।
अकवाल

1
उपरोक्त पोस्ट को .py.py /b.py ’का उपयोग करके संपादित करें की जाँच करें। वह उपयोग नहीं करता है from x import y, और अभी भी परिपत्र आयात त्रुटि मिलती है
ग्रेग एनिस

2
यह पूरी तरह से सच नहीं है। जैसे कि आयात * से, यदि आप शीर्ष स्तर पर, परिपत्र आयात में एक तत्व तक पहुंचने का प्रयास करते हैं, तो इससे पहले कि स्क्रिप्ट अपने रन को पूरा करती है, तो आपके पास एक ही मुद्दा होगा। उदाहरण के लिए यदि आप एक पैकेज को दूसरे से एक पैकेज में वैश्विक सेट कर रहे हैं, और वे दोनों एक दूसरे को शामिल करते हैं। मैं बेस क्लास में किसी ऑब्जेक्ट के लिए एक मैला फैक्ट्री बनाने के लिए ऐसा कर रहा था, जहां वह ऑब्जेक्ट कई उपवर्गों में से एक हो सकता है और उपयोग करने वाले कोड के बारे में पता करने की आवश्यकता नहीं है, जो वास्तव में बना रहा था।
एरोनम

3
@ अकावल वास्तव में नहीं। वह केवल उन नामों को आयात करेगा जो importकथन निष्पादित होने पर उपलब्ध हैं । तो यह त्रुटि नहीं करेगा, लेकिन आपको वे सभी चर नहीं मिल सकते हैं जिनकी आप अपेक्षा करते हैं।
अगस्तुर

3
ध्यान दें, यदि आप करते हैं from foo import *और from bar import *निष्पादित की गई सभी चीजें fooप्रारंभिक चरण में हैं bar, और वास्तविक कार्यों को barअभी तक परिभाषित नहीं किया गया है ...
Martian2049

100

चक्रीय आयात समाप्त हो जाते हैं, लेकिन आपको मॉड्यूल इनिशियलाइज़ेशन के दौरान चक्रीय-आयातित मॉड्यूल का उपयोग न करने के लिए सावधान रहने की आवश्यकता है।

निम्नलिखित फाइलों पर विचार करें:

a.py:

print "a in"
import sys
print "b imported: %s" % ("b" in sys.modules, )
import b
print "a out"

b.py:

print "b in"
import a
print "b out"
x = 3

यदि आप थिंकपैड निष्पादित करते हैं, तो आपको निम्नलिखित मिलेंगे:

$ python a.py
a in
b imported: False
b in
a in
b imported: True
a out
b out
a out

B.py? S के दूसरे आयात में (दूसरे में) a in ) , Python दुभाषिया bफिर से आयात नहीं करता है , क्योंकि यह मॉड्यूल में पहले से ही मौजूद है।

आप का उपयोग करने का प्रयास करें b.xसेa मॉड्यूल आरंभीकरण के दौरान, आप एक मिल जाएगा AttributeError

निम्नलिखित पंक्ति को इसमें संलग्न करें a.py:

print b.x

फिर, आउटपुट है:

$ python a.py
a in                    
b imported: False
b in
a in
b imported: True
a out
Traceback (most recent call last):
  File "a.py", line 4, in <module>
    import b
  File "/home/shlomme/tmp/x/b.py", line 2, in <module>
    import a
 File "/home/shlomme/tmp/x/a.py", line 7, in <module>
    print b.x
AttributeError: 'module' object has no attribute 'x'

इसका कारण यह है कि मॉड्यूल आयात पर निष्पादित किए जाते हैं और समय b.xपर एक्सेस किए जाने पर, लाइन x = 3को अभी तक निष्पादित नहीं किया गया है, जो केवल उसके बाद होगा b out


14
यह बहुत समस्या की व्याख्या करता है, लेकिन समाधान के बारे में कैसे? हम x को ठीक से कैसे आयात और प्रिंट कर सकते हैं? ऊपर दिए गए दूसरे उपाय ने मेरे लिए काम नहीं किया
mehmet

मुझे लगता है कि अगर आप के __name__बजाय इसका इस्तेमाल करते हैं तो यह जवाब बहुत फायदा पहुंचाएगा 'a'। शुरुआत में, मैं पूरी तरह से उलझन में था कि एक फाइल को दो बार क्यों निष्पादित किया जाएगा।
बरगी

30

जैसा कि अन्य उत्तर बताते हैं कि यह पैटर्न अजगर में स्वीकार्य है:

def dostuff(self):
     from foo import bar
     ...

जब फ़ाइल को अन्य मॉड्यूल द्वारा आयात किया जाता है तो आयात विवरण के निष्पादन से बचना होगा। केवल अगर कोई तार्किक परिपत्र निर्भरता है, तो यह विफल हो जाएगा।

अधिकांश परिपत्र आयात वास्तव में तार्किक परिपत्र आयात नहीं ImportErrorहैं, बल्कि इस तरह से त्रुटियों को बढ़ाते हैंimport() से पूरी फ़ाइल के शीर्ष स्तर के बयानों का मूल्यांकन किया जाता है।

ImportErrorsयदि आप सकारात्मक रूप से शीर्ष पर अपने आयात चाहते हैं तो इनसे लगभग हमेशा बचा जा सकता है :

इस परिपत्र आयात पर विचार करें:

ऐप ए

# profiles/serializers.py

from images.serializers import SimplifiedImageSerializer

class SimplifiedProfileSerializer(serializers.Serializer):
    name = serializers.CharField()

class ProfileSerializer(SimplifiedProfileSerializer):
    recent_images = SimplifiedImageSerializer(many=True)

ऐप बी

# images/serializers.py

from profiles.serializers import SimplifiedProfileSerializer

class SimplifiedImageSerializer(serializers.Serializer):
    title = serializers.CharField()

class ImageSerializer(SimplifiedImageSerializer):
    profile = SimplifiedProfileSerializer()

डेविड बेज़लेज़ से उत्कृष्ट टॉक मॉड्यूल और पैकेज: लाइव और लेट डाई! -1:54:00 अजगर 2015 , यहाँ अजगर में परिपत्र आयात से निपटने का एक तरीका है:

try:
    from images.serializers import SimplifiedImageSerializer
except ImportError:
    import sys
    SimplifiedImageSerializer = sys.modules[__package__ + '.SimplifiedImageSerializer']

यह आयात करने की कोशिश करता है SimplifiedImageSerializerऔर अगर ImportErrorउठाया जाता है, क्योंकि यह पहले से ही आयात किया गया है, तो यह इसे आयातक से खींच लेगा।

PS: आपको डेविड बेज़ले की आवाज़ में इस पूरी पोस्ट को पढ़ना होगा।


9
यदि मॉड्यूल पहले से ही आयात किया गया है तो ImportError को उठाया नहीं गया है। मॉड्यूल को कई बार आयात किया जा सकता है जैसा कि आप चाहते हैं कि "आयात करें? आयात करें?" ठीक है।
योरस

9

मुझे यहाँ एक उदाहरण मिला जिसने मुझे मारा!

foo.py

import bar

class gX(object):
    g = 10

bar.py

from foo import gX

o = gX()

main.py

import foo
import bar

print "all done"

कमांड लाइन पर: $ अजगर main.py

Traceback (most recent call last):
  File "m.py", line 1, in <module>
    import foo
  File "/home/xolve/foo.py", line 1, in <module>
    import bar
  File "/home/xolve/bar.py", line 1, in <module>
    from foo import gX
ImportError: cannot import name gX

2
आपने इसे कैसे ठीक किया? मैं अपने खुद की एक समस्या को ठीक करने परिपत्र आयात समझने की कोशिश कर रहा है कि लगता बहुत करने के लिए आप क्या कर रहे ... समान
c089

12
त्रुटि ... मुझे लगता है कि मैंने अपनी समस्या को इस अविश्वसनीय रूप से बदसूरत हैक के साथ तय किया। {{{यदि sys.modules में 'foo.bar' नहीं है: foo import bar से और: बार = sys.modules ['foo.bar']}}}}, व्यक्तिगत रूप से, मुझे लगता है कि परिपत्र आयात बुरे कोड में एक बड़ी चेतावनी संकेत हैं डिजाइन ...
c089

5
@ c089, या आप बस चल सकता import barमें foo.pyकरने के लिए अंत
warvariuc

5
यदि barऔर fooदोनों का उपयोग करना चाहिए gX, 'साफ' समाधान डाल करने के लिए है gXएक और मॉड्यूल में और दोनों fooऔर barआयात कि मॉड्यूल। (इस अर्थ में सबसे साफ है कि कोई छिपी हुई शब्दार्थ निर्भरता नहीं हैं।)
टिम वाइल्डर

2
टिम के पास एक अच्छी बात है। मूल रूप से यह इसलिए है क्योंकि barयह भी gXफू में नहीं मिल सकता है । परिपत्र आयात अपने आप ठीक है, लेकिन यह सिर्फ इतना gXहै कि इसे आयात किए जाने पर परिभाषित नहीं किया गया है।
मार्टियन २०४

9

मॉड्यूल थिंकपैड:

import b
print("This is from module a")

मॉड्यूल b.py

import a
print("This is from module b")

आउटपुट "मॉड्यूल" चल रहा है:

>>> 
'This is from module a'
'This is from module b'
'This is from module a'
>>> 

यह 3 लाइनों का उत्पादन करता है, जबकि इसे परिपत्र आयात के कारण इनफिनिटिव का उत्पादन करना था। "मॉड्यूल" को चलाने के दौरान लाइन से लाइन क्या होती है यहां सूचीबद्ध है:

  1. पहली पंक्ति है import b। इसलिए यह मॉड्यूल बी का दौरा करेगा
  2. मॉड्यूल बी पर पहली पंक्ति है import a। इसलिए यह मॉड्यूल ए का दौरा करेगा
  3. मॉड्यूल में पहली पंक्ति एक है, import bलेकिन ध्यान दें कि इस लाइन को अब फिर से निष्पादित नहीं किया जाएगा , क्योंकि अजगर में हर फाइल सिर्फ एक बार के लिए एक आयात लाइन निष्पादित करती है, यह कोई फर्क नहीं पड़ता कि इसे कहां या कब निष्पादित किया जाता है। इसलिए यह अगली पंक्ति में जाएगा और प्रिंट करेगा "This is from module a"
  4. मॉड्यूल बी से पूरे मॉड्यूल का दौरा करने के बाद, हम अभी भी मॉड्यूल बी पर हैं। तो अगली लाइन छपेगी"This is from module b"
  5. मॉड्यूल बी लाइनों को पूरी तरह से निष्पादित किया जाता है। इसलिए हम मॉड्यूल पर वापस जाएंगे जहां हमने मॉड्यूल बी शुरू किया है।
  6. आयात b लाइन को पहले ही निष्पादित किया जा चुका है और फिर से निष्पादित नहीं किया जाएगा। अगली पंक्ति छपेगी "This is from module a"और कार्यक्रम समाप्त हो जाएगा।

4

मैं यहां अजगर के जवाब से पूरी तरह सहमत हूं। लेकिन मैंने कुछ कोडों पर ठोकर खाई है जो परिपत्र आयात के साथ त्रुटिपूर्ण थे और यूनिट परीक्षणों को जोड़ने की कोशिश करते समय मुद्दों का कारण बने। तो जल्दी से सब कुछ बदलने के बिना इसे पैच करें आप डायनेमिक आयात करके समस्या को हल कर सकते हैं।

# Hack to import something without circular import issue
def load_module(name):
    """Load module using imp.find_module"""
    names = name.split(".")
    path = None
    for name in names:
        f, path, info = imp.find_module(name, path)
        path = [path]
    return imp.load_module(name, f, path[0], info)
constants = load_module("app.constants")

फिर से, यह एक स्थायी समाधान नहीं है, लेकिन किसी ऐसे व्यक्ति की मदद कर सकता है जो बहुत अधिक कोड को बदले बिना आयात त्रुटि को ठीक करना चाहता है।

चीयर्स!


3

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

एक फ़ाइल को दर्ज करें

from b import B

class A:
    @staticmethod
    def save_result(result):
        print('save the result')

    @staticmethod
    def do_something_a_ish(param):
        A.save_result(A.use_param_like_a_would(param))

    @staticmethod
    def do_something_related_to_b(param):
        B.do_something_b_ish(param)

फ़ाइल

from a import A

class B:
    @staticmethod
    def do_something_b_ish(param):
        A.save_result(B.use_param_like_b_would(param))

इस स्थिति में, एक स्थिर विधि को एक अलग फ़ाइल में ले जाना, कहते हैं c.py:

फ़ाइल c.py

def save_result(result):
    print('save the result')

save_resultए से विधि को हटाने की अनुमति देगा , और इस प्रकार बी में ए से आयात को हटाने की अनुमति देगा:

फ़ाइल पुनर्प्राप्त फ़ाइल

from b import B
from c import save_result

class A:
    @staticmethod
    def do_something_a_ish(param):
        A.save_result(A.use_param_like_a_would(param))

    @staticmethod
    def do_something_related_to_b(param):
        B.do_something_b_ish(param)

फ़ाइल b.py को पुनःप्राप्त

from c import save_result

class B:
    @staticmethod
    def do_something_b_ish(param):
        save_result(B.use_param_like_b_would(param))

सारांश में, यदि आपके पास एक उपकरण है (उदाहरण pylint या PyCharm) जो उन तरीकों पर रिपोर्ट करता है जो स्थिर हो सकते हैं, तो बस staticmethodउन पर एक डेकोरेटर फेंकना चेतावनी को चुप करने का सबसे अच्छा तरीका नहीं हो सकता है। भले ही विधि वर्ग से संबंधित लगती है, लेकिन इसे अलग करना बेहतर हो सकता है, खासकर यदि आपके पास कई निकटता से संबंधित मॉड्यूल हैं जिनकी समान कार्यक्षमता की आवश्यकता हो सकती है और आप DRY सिद्धांतों का अभ्यास करना चाहते हैं।


2

परिपत्र आयात भ्रामक हो सकता है क्योंकि आयात दो चीजें करता है:

  1. यह आयातित मॉड्यूल कोड निष्पादित करता है
  2. मॉड्यूल वैश्विक प्रतीक तालिका आयात करने के लिए आयातित मॉड्यूल जोड़ता है

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

सर्कुलर आयात हर कीमत पर टाले जाने वाली अंतिम बुराई नहीं है। फ्लास्क जैसी कुछ रूपरेखाओं में वे काफी स्वाभाविक हैं और उन्हें समाप्त करने के लिए आपके कोड को ट्विक करना कोड को बेहतर नहीं बनाता है।

main.py

print 'import b'
import b
print 'a in globals() {}'.format('a' in globals())
print 'import a'
import a
print 'a in globals() {}'.format('a' in globals())
if __name__ == '__main__':
    print 'imports done'
    print 'b has y {}, a is b.a {}'.format(hasattr(b, 'y'), a is b.a)

b.by

print "b in, __name__ = {}".format(__name__)
x = 3
print 'b imports a'
import a
y = 5
print "b out"

a.py

print 'a in, __name__ = {}'.format(__name__)
print 'a imports b'
import b
print 'b has x {}'.format(hasattr(b, 'x'))
print 'b has y {}'.format(hasattr(b, 'y'))
print "a out"

टिप्पणियों के साथ अजगर मेनफ्रेम आउटपुट

import b
b in, __name__ = b    # b code execution started
b imports a
a in, __name__ = a    # a code execution started
a imports b           # b code execution is already in progress
b has x True
b has y False         # b defines y after a import,
a out
b out
a in globals() False  # import only adds a to main global symbol table 
import a
a in globals() True
imports done
b has y True, a is b.a True # all b objects are available

1

मैंने निम्नलिखित तरीके से समस्या को हल किया, और यह बिना किसी त्रुटि के अच्छी तरह से काम करता है। दो फ़ाइलों पर विचार करें a.pyऔर b.py

मैंने a.pyइसे जोड़ा और यह काम किया।

if __name__ == "__main__":
        main ()

a.py:

import b
y = 2
def main():
    print ("a out")
    print (b.x)

if __name__ == "__main__":
    main ()

b.py:

import a
print ("b out")
x = 3 + a.y

मुझे जो आउटपुट मिलता है

>>> b out 
>>> a out 
>>> 5

0

ठीक है, मुझे लगता है कि मेरे पास एक बहुत अच्छा समाधान है। मान लें कि आपके पास फ़ाइल aऔर फ़ाइल है b। आप एक है defया एक classफ़ाइल में bहै कि आप मॉड्यूल में उपयोग करना चाहते हैं a, लेकिन आप कुछ और ही है, या तो एक def, classया फ़ाइल से चर aहै कि आप अपने परिभाषा या फाइल में कक्षा में की जरूरत है b। फ़ाइल aमें फ़ंक्शन या क्लास को कॉल करने के बाद , aफ़ाइल में b, लेकिन फ़ाइल से फ़ंक्शन या क्लास को कॉल करने से पहले आप क्या कर सकते हैंb आपको फ़ाइल की आवश्यकता होती है a, import b फिर कहते हैं , और यहाँ मुख्य भाग है फ़ाइल में सभी परिभाषाओं या कक्षाओं में bजिनकी आवश्यकता हैdef याclass फ़ाइल सेa(चलो इसे कहते हैं CLASS), आप कहते हैंfrom a import CLASS

यह काम करता है क्योंकि आप फ़ाइल में bकिसी भी आयात विवरण को निष्पादित करने के बिना पायथन आयात कर सकते हैं b, और इस प्रकार आप किसी भी परिपत्र आयात को हटा सकते हैं।

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

फाइल करें:

class A(object):

     def __init__(self, name):

         self.name = name

CLASS = A("me")

import b

go = B(6)

go.dostuff

फ़ाइल बी:

class B(object):

     def __init__(self, number):

         self.number = number

     def dostuff(self):

         from a import CLASS

         print "Hello " + CLASS.name + ", " + str(number) + " is an interesting number."

देखा।


from a import CLASSवास्तव में ऑरेकल में सभी कोड निष्पादित करना नहीं छोड़ता है। यह वास्तव में होता है: (1) ऑरेकल का सभी कोड एक विशेष मॉड्यूल "__main__" के रूप में चलता है। (2) पर import b, बी-थोरो में शीर्ष-स्तरीय कोड चलता है (वर्ग बी को परिभाषित करता है) और फिर "__m____" पर नियंत्रण रखता है। (३) "__main__" अंततः नियंत्रण को पास करता है go.dostuff()। (4) जब डस्टफ़ () आता है import a, तो यह सभी कोड को फिर से थिंकपैड में चलाता है , इस बार मॉड्यूल "ए" के रूप में; तब यह नए मॉड्यूल "a" से CLASS ऑब्जेक्ट को आयात करता है। तो वास्तव में, यह उतनी ही अच्छी तरह से काम करेगा अगर आप import aकहीं भी बी-बीकॉम में उपयोग करते हैं।
मथायस फ्रीप
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.