आईडी () फ़ंक्शन किसके लिए उपयोग किया जाता है?


99

मैंने पायथन 2 डॉक्स पढ़ा और id()फ़ंक्शन पर ध्यान दिया :

किसी वस्तु की "पहचान" लौटाएं। यह एक पूर्णांक (या लंबा पूर्णांक) है जो अपने जीवनकाल में इस वस्तु के लिए अद्वितीय और स्थिर रहने की गारंटी है। गैर-अतिव्यापी जीवनकाल वाली दो वस्तुओं में एक ही आईडी () मूल्य हो सकता है।

CPython कार्यान्वयन विवरण: यह मेमोरी में ऑब्जेक्ट का पता है।

इसलिए, मैंने id()एक सूची का उपयोग करके प्रयोग किया :

>>> list = [1,2,3]
>>> id(list[0])
31186196
>>> id(list[1])
31907092 // increased by 896
>>> id(list[2])
31907080 // decreased by 12

पूर्णांक फ़ंक्शन से क्या लौटा है? क्या यह C में मेमोरी एड्रेस का पर्याय है? यदि हां, तो पूर्णांक डेटा प्रकार के आकार के अनुरूप क्यों नहीं है?

id()अभ्यास में कब प्रयोग किया जाता है?


4
सिर्फ इसलिए कि आप एक स्क्रिप्टिंग भाषा में डेटा संरचना में 32bit int स्टोर (कहते हैं) का मतलब यह नहीं है कि आप 32 बिट्स अधिक मेमोरी का उपयोग कर रहे हैं। आपके द्वारा संग्रहीत किसी भी डेटा के साथ हमेशा मेटाडेटा संलग्न है। प्रकार, आकार, लंबाई, ब्ला ब्ला ब्ला।
— मार्क बी

Cpython एक ढेर से आवंटित करता है जो वस्तुओं के रूप में उखड़ जाता है और मॉलोकॉल्ड और फ्री होल्ड होता है।
— tdelaney

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

जवाबों:


156

आपकी पोस्ट कई सवाल पूछती है:

फ़ंक्शन से दी गई संख्या क्या है?

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

क्या C में मेमोरी एड्रेस के साथ भी ऐसा ही है?

वैचारिक रूप से, हाँ, इसमें वे दोनों अपने जीवनकाल के दौरान अपने ब्रह्मांड में अद्वितीय होने की गारंटी देते हैं। और पायथन के एक विशेष कार्यान्वयन में, यह वास्तव में संबंधित सी ऑब्जेक्ट का मेमोरी एड्रेस है।

यदि हाँ, तो डेटा प्रकार के आकार से तुरंत संख्या क्यों नहीं बढ़ती (मुझे लगता है कि यह अंतर होगा)?

क्योंकि एक सूची एक सरणी नहीं है, और एक सूची तत्व एक संदर्भ है, एक वस्तु नहीं है।

हम वास्तव में id( )फ़ंक्शन का उपयोग कब करते हैं ?

शायद ही कभी। id()(या इसके समतुल्य) का उपयोग isऑपरेटर में किया जाता है ।


हम आईडी () का उपयोग आमतौर पर प्रदर्शन उद्देश्य में करते हैं जैसे कि stackoverflow.com/questions/17246693/…
— Nabin

49

यह स्मृति में वस्तु के स्थान की पहचान है ...

यह उदाहरण आपको अवधारणा को थोड़ा और समझने में मदद कर सकता है।

foo = 1
bar = foo
baz = bar
fii = 1

print id(foo)
print id(bar)
print id(baz)
print id(fii)

> 1532352
> 1532352
> 1532352
> 1532352

ये सभी स्मृति में एक ही स्थान पर इंगित करते हैं, यही वजह है कि उनके मूल्य समान हैं। उदाहरण में, 1केवल एक बार संग्रहीत किया जाता है, और कुछ और जो इंगित करता है 1कि स्मृति स्थान को संदर्भित करेगा।


9
लेकिन अगर आप -5 से 256 की सीमा से अधिक संख्या का उपयोग करते हैं, तो आपको fii वेरिएबल के लिए एक ही आईडी नहीं मिलेगी।
— २av’१

यह बेहद दिलचस्प है। क्या आप और शेयर कर सकते हैं?
— जूल

3
मुझे लगता है कि यह उत्तर भ्रामक है क्योंकि यह अधिकांश संख्याओं के लिए सही नहीं है; देखें "है" ऑपरेटर पूर्णांक के साथ अप्रत्याशित व्यवहार करता है ।
— केविनजी

8

id()संदर्भित (CPython में) ऑब्जेक्ट का पता लौटाता है, लेकिन आपका भ्रम इस तथ्य से आता है कि अजगर की सूची C सरणियों से बहुत अलग हैं। एक अजगर सूची में, प्रत्येक तत्व एक संदर्भ है । तो आप जो कर रहे हैं वह इस C कोड के समान है:

int *arr[3];
arr[0] = malloc(sizeof(int));
*arr[0] = 1;
arr[1] = malloc(sizeof(int));
*arr[1] = 2;
arr[2] = malloc(sizeof(int));
*arr[2] = 3;
printf("%p %p %p", arr[0], arr[1], arr[2]);

दूसरे शब्दों में, आप संदर्भ से पता और प्रिंट कर रहे हैं नहीं जहां अपनी सूची संग्रहीत किया जाता है के लिए एक भाषण रिश्तेदार।

मेरे मामले में, मैंने id()सी। कोड pythonसे कॉल करते समय C कोड पर लौटने के लिए अपारदर्शी हैंडल बनाने के लिए फ़ंक्शन को उपयोगी पाया है। ऐसा करते हुए, आप आसानी से इसके हैंडल से ऑब्जेक्ट को देखने के लिए एक शब्दकोश का उपयोग कर सकते हैं और यह अद्वितीय होने की गारंटी है।


7

रोब का जवाब (ऊपर दिया गया वोट) सही है। मैं जोड़ना चाहूंगा कि कुछ स्थितियों में आईडी का उपयोग करना उपयोगी है क्योंकि यह वस्तुओं की तुलना करने और उन वस्तुओं को खोजने की अनुमति देता है जो आपकी वस्तुओं को संदर्भित करती हैं।

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

हाल ही में मुझे एक पायथन / टिंकर ऐप के साथ यह समस्या हुई थी जहाँ एक पाठ प्रविष्टि क्षेत्र में संपादन पाठ ने पाठ को दूसरे में बदल दिया जैसे कि आप टाइप करते हैं :)

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

class democlass:
    classvar = 24

    def __init__(self, var):
        self.instancevar1 = var
        self.instancevar2 = 42

    def whoreferencesmylocalvars(self, fromwhere):
        return {__l__: {__g__
                    for __g__ in fromwhere
                        if not callable(__g__) and id(eval(__g__)) == id(getattr(self,__l__))
                    }
                for __l__ in dir(self)
                    if not callable(getattr(self, __l__)) and __l__[-1] != '_'
                }

    def whoreferencesthisclassinstance(self, fromwhere):
        return {__g__
                    for __g__ in fromwhere
                        if not callable(__g__) and id(eval(__g__)) == id(self)
                }

a = [1,2,3,4]
b = a
c = b
democlassinstance = democlass(a)
d = democlassinstance
e = d
f = democlassinstance.classvar
g = democlassinstance.instancevar2

print( 'My class instance is of', type(democlassinstance), 'type.')
print( 'My instance vars are referenced by:', democlassinstance.whoreferencesmylocalvars(globals()) )
print( 'My class instance is referenced by:', democlassinstance.whoreferencesthisclassinstance(globals()) )

उत्पादन:

My class instance is of <class '__main__.democlass'> type.
My instance vars are referenced by: {'instancevar2': {'g'}, 'classvar': {'f'}, 'instancevar1': {'a', 'c', 'b'}}
My class instance is referenced by: {'e', 'd', 'democlassinstance'}

वेरिएबल नामों में अंडरस्कोर का उपयोग नाम कॉलिशन को रोकने के लिए किया जाता है। फ़ंक्शंस "Fromwhere" तर्क का उपयोग करते हैं ताकि आप उन्हें बता सकें कि संदर्भों की खोज कहाँ से शुरू करें। यह तर्क एक फ़ंक्शन द्वारा भरा गया है जो किसी दिए गए नाम स्थान में सभी नामों को सूचीबद्ध करता है। ग्लोबल्स () ऐसा ही एक फंक्शन है।


महान व्याख्या!
— नीरज वर्मा

5

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

प्रत्येक मान एक आईडी है, जो एक अद्वितीय संख्या से संबंधित है जहां इसे कंप्यूटर की मेमोरी में संग्रहीत किया जाता है।


5

यदि आप अजगर 3.4.1 का उपयोग कर रहे हैं तो आपको अपने प्रश्न का एक अलग उत्तर मिलता है।

list = [1,2,3]
id(list[0])
id(list[1])
id(list[2])

रिटर्न:

1705950792   
1705950808  # increased by 16   
1705950824  # increased by 16

पूर्णांक -5के लिए 256एक निरंतर आईडी है, और इसे कई बार अपने आईडी परिवर्तन नहीं करता है, अन्य सभी संख्या के विपरीत खोजने से पहले या बाद में यह अलग आईडी है कि हर बार जब आप इसे खोजने के लिए है। से संख्या -5को 256बढ़ते क्रम में पहचान-पत्र है और से अलग 16।

id()फ़ंक्शन द्वारा लौटाई गई संख्या मेमोरी में संग्रहीत प्रत्येक आइटम को दी गई एक अद्वितीय आईडी है और यह सी में मेमोरी स्थान के समान ही अनुरूप है।


2

जवाब बहुत ज्यादा कभी नहीं है। आईडी मुख्य रूप से पायथन में आंतरिक रूप से उपयोग की जाती है।

औसत पायथन प्रोग्रामर को शायद id()अपने कोड में उपयोग करने की आवश्यकता नहीं होगी ।


3
शायद मैं औसत नहीं हूं, लेकिन मैं id()काफी थोड़ा उपयोग करता हूं । मेरे सिर के ऊपर से दो उपयोग के मामले: एक (हाथ से लुढ़का हुआ, तदर्थ) पहचान ताना और एक repr()वस्तु के लिए एक रिवाज जहां पहचान मायने रखती है लेकिन डिफ़ॉल्ट reprउपयुक्त नहीं है।

5
@ डायलेन मैं उन सामान्य मामलों पर बहस नहीं करूंगा।
— गारेथ लैटी

2

isऑपरेटर की जाँच करने के लिए कि क्या दो वस्तुओं समान हैं (जैसा कि बराबर के खिलाफ) इसे इस्तेमाल करता है। वास्तविक मूल्य जो लौटाया जाता है id()वह बहुत अधिक कभी किसी चीज़ के लिए उपयोग नहीं किया जाता है क्योंकि इसका वास्तव में कोई अर्थ नहीं है, और यह प्लेटफ़ॉर्म-निर्भर है।


2

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

इसलिए, जब तक आप भाषा में एक पूर्ण गुरु नहीं होते हैं, तो आप पिछले तत्व के आधार पर अपनी सूची के अगले तत्व की आईडी निर्धारित नहीं कर सकते, क्योंकि आप नहीं जानते कि भाषा तत्वों के साथ क्या आवंटित करती है।


1
वास्तव में, पायथन गुरु होने से किसी भी वस्तु की भविष्यवाणी करने का अधिक उपयोग नहीं होगा id()। आपको प्रश्न में स्मृति प्रबंधकों (बहुवचन!) के साथ गहन रूप से परिचित होना होगा, किसी समय उनकी सटीक स्थिति को जानना होगा, और उस सटीक क्रम को जानना होगा जिसमें ऑब्जेक्ट आवंटित किए गए हैं। दूसरे शब्दों में: नहीं होने वाला।

यदि आप संभावित स्मृति प्रबंधकों सहित इसकी सभी बारीकियों को जानते हैं, तो आप एक पूर्ण अजगर गुरु हैं।
— लाजोस अर्पाद

1
पायथन को जानना और एक विशेष कार्यान्वयन (जैसे CPython) को जानना दो पूरी तरह से अलग चीजें हैं। और यहां तक ​​कि सीपीथॉन को अंदर से जानने से भी मदद नहीं मिलेगी, क्योंकि कई मेमोरी मैनेजर सीपीथॉन कॉल कर रहे हैं जो कि सीपीथॉन का हिस्सा नहीं हैं, लेकिन संबंधित ऑपरेटिंग सिस्टम का हिस्सा हैं। और जैसा कि मैंने पहले भी कहा है, यहां तक ​​कि इन सभी गैर-पायथन चीजों को जानने से आपको मदद नहीं मिलेगी, क्योंकि वास्तविक पते मेमोरी प्रबंधकों की रन-टाइम स्थिति पर निर्भर करते हैं, और कभी-कभी यादृच्छिक भी होते हैं।

1
उल्लेख करने के लिए नहीं, यह जानना बेकार होगा, क्योंकि इस तरह की बात पर भरोसा करना कार्यान्वयन विस्तार पर निर्भर करेगा और इसलिए नाजुक और अनम्य होगा।
— गारेथ लैटी

2

मुझे id()लॉगिंग में मान का उपयोग करने का एक विचार है ।
यह सस्ता है और यह काफी कम है।
मेरे मामले में मैं बवंडर का उपयोग करता हूं और id()वेब सॉकेट द्वारा फ़ाइल में बिखरे और मिश्रित किए गए समूह संदेशों के लिए एक लंगर देना चाहूंगा।


0

अजगर के रूप में 3 आईडी एक चर नहीं एक मान को सौंपा गया है। इसका मतलब है कि यदि आप नीचे दिए गए दो कार्य बनाते हैं, तो सभी तीन आईडी समान हैं।

>>> def xyz():
...     q=123
...     print(id(q))
...
>>> def iop():
...     w=123
...     print(id(w))
>>> xyz()
1650376736
>>> iop()
1650376736
>>> id(123)
1650376736

हालांकि यह विरोधाभास पिछले स्पष्टीकरणों से प्रतीत होता है कि ऐसा होता है और मुझे नहीं पता कि क्यों। कोई स्पष्टीकरण? उदाहरण के लिए x [0] = "abc" x [1] = "def" q = ["abc", "def"]। Id (x) == Id (q) True है। संयोग?
— VMMF

0

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

>>> x=1000
>>> y=1000
>>> id(x)==id(y)
False
>>> id(x)
4312240944
>>> id(y)
4312240912
>>> id(1000)
4312241104
>>> x=1000
>>> id(x)
4312241104
>>> y=1000
>>> id(y)
4312241200

आपको वस्तुओं के रूप में दाईं ओर की हर चीज के बारे में सोचने की जरूरत है। हर बार जब आप असाइनमेंट बनाते हैं - आप नई ऑब्जेक्ट बनाते हैं और इसका मतलब है कि नई आईडी। बीच में आप एक "जंगली" ऑब्जेक्ट देख सकते हैं जो केवल फ़ंक्शन के लिए बनाया गया है - आईडी (1000)। इसलिए, यह आजीवन केवल कोड की उस पंक्ति के लिए है। यदि आप अगली पंक्ति की जाँच करते हैं - तो आप देखते हैं कि जब हम नया चर x बनाते हैं, तो उसमें उसी जंगली वस्तु के समान आईडी होती है। बहुत ज्यादा यह मेमोरी एड्रेस की तरह काम करता है।


0

केयरफुल बनें (नीचे दिए गए जवाब के बारे में) ... यह केवल सच है क्योंकि 123 -5 और 256 के बीच है ...

In [111]: q = 257                                                         

In [112]: id(q)                                                            
Out[112]: 140020248465168

In [113]: w = 257                                                         

In [114]: id(w)                                                           
Out[114]: 140020274622544

In [115]: id(257)                                                         
Out[115]: 140020274622768
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.