Skip to content
This page has been auto-translated and may contain errors.View in English

वेरिएबल और डेटा प्रकार

हर प्रोग्राम को चीज़ें याद रखनी होती हैं। एक क्विज़ को खिलाड़ी का नाम चाहिए। एक गेम को मौजूदा स्कोर चाहिए। एक मौसम स्क्रिप्ट को वह शहर चाहिए जो आप जाँच रहे हैं। Python इसके लिए वेरिएबल का उपयोग करती है: वे नाम जो आप मानों से जोड़ते हैं ताकि उन्हें पूरे प्रोग्राम में इस्तेमाल कर सकें।

वेरिएबल मानों के नामांकित संदर्भ होते हैं। Python = के दाईं ओर के ऑब्जेक्ट से एक नाम बाँधती है और आपको उसे कभी भी फिर से बाँधने देती है। प्रकार नाम पर नहीं, बल्कि मान पर रहता है।

Python में, एक वेरिएबल एक नाम बाइंडिंग है: एक namespace में एक संदर्भ जो रनटाइम पर किसी ऑब्जेक्ट को resolve करता है। ऑब्जेक्ट प्रकार वहन करते हैं; नाम नहीं। यही डायनामिक टाइपिंग है: एक ही नाम अलग-अलग कथनों में पूरी तरह से भिन्न प्रकार के ऑब्जेक्ट को संदर्भित कर सकता है।

python
player_name = "अर्जुन"
score       = 0
city        = "नई दिल्ली"

तीन पंक्तियाँ। तीन चीज़ें जो Python अब याद रखती है। बाद में उन नामों में से कोई भी उपयोग करें और Python आपको वह मान वापस दे देगी।

प्रत्येक पंक्ति एक बाइंडिंग बनाती है: बाईं ओर का नाम दाईं ओर के ऑब्जेक्ट को संदर्भित करता है। Python पहले दाईं ओर का मूल्यांकन करती है, फिर बाइंडिंग बनाती है।

प्रत्येक असाइनमेंट मौजूदा scope के local namespace में एक नाम बनाता है या उसे फिर से बाँधता है। Python बाइंडिंग प्रभावी होने से पहले दाईं ओर के expression का पूरी तरह मूल्यांकन करती है। नाम अपना कोई प्रकार की जानकारी नहीं रखता।

एक मान संग्रहीत करना

= चिह्न लगभग सभी को गणित की कक्षा से आने पर उलझन में डालता है। Python में, = का अर्थ "बराबर है" नहीं है। इसका अर्थ है इस मान को इस नाम से संग्रहीत करो। इसे बाएँ से दाएँ पढ़ें:

python
city = "नई दिल्ली"

city को "नई दिल्ली" मिलता है। आप Python को बता रहे हैं: "नई दिल्ली" याद रखो और उसे city नाम दो।

आप किसी भी समय वेरिएबल का मान बदल सकते हैं। Python बस सबसे हालिया मान का उपयोग करती है:

python
score = 0
score = 10   # score अब 10 है
score = 15   # score अब 15 है

= असाइनमेंट है: यह मौजूदा scope में एक नाम को किसी ऑब्जेक्ट से बाँधता है। वेरिएबल को अपडेट करने का एक मानक शॉर्टहैंड augmented assignment है:

python
score = 0
score += 10   # इसके समान: score = score + 10
score *= 2    # इसके समान: score = score * 2

आप एक साथ कई नाम भी बाँध सकते हैं:

python
x, y, z = 1, 2, 3
a = b = 0        # दोनों शून्य से शुरू होते हैं

असाइनमेंट एक नाम को किसी ऑब्जेक्ट से बाँधता है; यह किसी कंटेनर में मान की प्रतिलिपि नहीं बनाता। दो नाम एक ही ऑब्जेक्ट को संदर्भित कर सकते हैं:

python
a = "hello"
b = a
print(id(a) == id(b))   # True (मेमोरी में एक ही ऑब्जेक्ट)

b = "world"             # b एक नए ऑब्जेक्ट से पुनः बाँधा गया
print(id(a) == id(b))   # False
print(a)                # अभी भी "hello": b को पुनः बाँधने से a प्रभावित नहीं हुआ

id() ऑब्जेक्ट की पहचान (CPython में उसका मेमोरी पता) लौटाता है। नाम बाइंडिंग और कॉपी करने के बीच यह अंतर mutable ऑब्जेक्ट जैसे list और dict के साथ अधिक महत्वपूर्ण होता है, जो बाद के अध्यायों में शामिल है।

Type annotations static analysis tools के लिए अपेक्षित प्रकारों को दस्तावेज़ित करते हैं। इनका रनटाइम पर कोई प्रभाव नहीं होता:

python
name:  str   = "अर्जुन"
score: int   = 0
ratio: float = 0.85

अपने वेरिएबल का नाम रखना

नाम आप चुनते हैं। Python के कुछ कठोर नियम हैं, और समुदाय उन परंपराओं का पालन करता है जिन्हें पहले दिन से अपनाना उचित है। स्पष्ट नाम कोड को हफ्तों बाद भी पठनीय बनाते हैं। रहस्यमय नाम परेशानी का कारण बनते हैं।

Python identifier syntax के नियमों का एक छोटा सेट लागू करती है। उससे परे, PEP 8 परंपराएँ हर Python कोडबेस और टूल में वास्तविक मानक हैं।

Python के identifier syntax नियम न्यूनतम हैं। PEP 8 परंपराएँ interpreter द्वारा लागू नहीं की जाती हैं लेकिन linters, type checkers और हर professional Python कोडबेस द्वारा मानी जाती हैं। इनसे विचलन घर्षण पैदा करता है।

Python द्वारा लागू किए गए नियम:

  • केवल अक्षर, अंक और अंडरस्कोर। कोई स्थान या हाइफन नहीं।
  • अक्षर या अंडरस्कोर से शुरू होना चाहिए, कभी अंक से नहीं
  • केस-संवेदी: score, Score, और SCORE तीन अलग-अलग वेरिएबल हैं

सभी के द्वारा अनुसरण की जाने वाली परंपराएँ (PEP 8):

चीज़शैलीउदाहरण
वेरिएबल और फ़ंक्शनsnake_caseuser_name, total_price
स्थिरांकUPPER_SNAKE_CASEMAX_RETRIES, BASE_URL
क्लासPascalCaseUserAccount, DataLoader
python
# स्पष्ट नाम, एक नज़र में पठनीय
user_name    = "अर्जुन"
total_price  = 49.99
is_logged_in = True
MAX_RETRIES  = 3

# एक घंटे के भीतर आपको पछतावा होगा
x   = "अर्जुन"
tp  = 49.99
b   = True

एक जाल जो जल्दी जानना ज़रूरी है: किसी वेरिएबल का नाम Python के built-in जैसे list, input, type, या print के नाम पर मत रखें। Python इसकी अनुमति देती है, लेकिन आप उस scope के बाकी हिस्से के लिए built-in को चुपचाप तोड़ देंगे और परिणामी त्रुटियाँ ढूंढना कठिन होती हैं।

Python के built-ins को shadow मत करें। list, type, input, print, या str को असाइन करना उस scope के बाकी हिस्से के लिए बिना किसी चेतावनी के built-in को overwrite कर देता है। यह एक silent bug है जिसे ढूंढना कष्टदायक हो सकता है।

UPPER_SNAKE_CASE एक परंपरा है, लागू नहीं। Python आपको बाद में MAX_RETRIES = 99 फिर से असाइन करने से नहीं रोकेगी। यह अन्य डेवलपर्स के लिए एक संकेत है, कुछ और नहीं।

किसी built-in को shadow करना एक local binding बनाता है जो सामान्य name lookup क्रम में built-in पर वरीयता लेता है। Built-in अभी भी builtins.print आदि के माध्यम से सुलभ है, लेकिन shadowing नाम सामान्य उपयोग में उसे छुपा देता है। UPPER_SNAKE_CASE का कोई language-level enforcement नहीं है। वास्तविक immutability गारंटी के लिए जो tools जाँच सकते हैं, annotation में typing.Final मानक दृष्टिकोण है।

आप क्या संग्रहीत कर सकते हैं

Python के चार प्रकार हैं जिनका उपयोग आप लगभग हर प्रोग्राम में करेंगे। Python यह समझ लेती है कि आप किस प्रकार का अर्थ रखते हैं, इस आधार पर कि आप मान कैसे लिखते हैं। आप कभी स्पष्ट रूप से एक प्रकार घोषित नहीं करते।

Python literal syntax से प्रकार का अनुमान लगाती है। ये चार प्रकार मूल मान-स्थान को कवर करते हैं; भाषा में बाकी सब कुछ इन्हीं के ऊपर बना है।

Python के चार primitive प्रकार प्रत्येक अलग-अलग मेमोरी layout, precision विशेषताओं और operation semantics वाले अलग runtime objects से map होते हैं। प्रकार ऑब्जेक्ट द्वारा निर्धारित होता है, नाम द्वारा नहीं।

पाठ (str)

कोई भी पाठ quote marks के अंदर जाता है, एकल या दोहरे। quotes Python को बताते हैं कि आपका अर्थ literal अक्षर हैं, न कि कोई वेरिएबल नाम। एक बार बनने के बाद, string को in place नहीं बदला जा सकता। Strings अध्याय उनके साथ आप जो कुछ भी कर सकते हैं वह सब कवर करता है।

python
player_name = "अर्जुन"
city        = "नई दिल्ली"
message     = 'खेल समाप्त'

यदि आपके पाठ में apostrophe है, तो उसे escape करने से बचने के लिए दोहरे quotes का उपयोग करें:

python
note = "यह एक अच्छा दिन है"
note = 'यह एक अच्छा दिन है'   # escape का उपयोग करके समान परिणाम

Strings एकल या दोहरे quotes में कोई भी पाठ रखती हैं। वे immutable हैं: कोई भी operation string को in place संशोधित नहीं करता; हर रूपांतरण एक नई string लौटाता है। यह performance के लिए महत्वपूर्ण है: loop के अंदर बार-बार + हर चरण पर एक नया string object बनाता है। Strings अध्याय कुशल विकल्प को कवर करता है।

python
player_name = "अर्जुन"
city        = "नई दिल्ली"
note        = "यह एक अच्छा दिन है"

str bytes नहीं बल्कि Unicode code points का एक immutable sequence है। len("café") 5 नहीं, 4 है। Immutability strings को hashable बनाती है: dict keys और set members के रूप में मान्य। CPython उन छोटी strings को intern करता है जो identifiers की तरह दिखती हैं; एक ही छोटे literal को असाइन किए गए दो वेरिएबल अक्सर मेमोरी में एक ही object साझा करते हैं। दोनों quote शैलियाँ समान objects बनाती हैं।

python
player_name = "अर्जुन"
city        = "नई दिल्ली"
note        = "यह एक अच्छा दिन है"

पूर्ण संख्याएँ (int)

पूर्ण संख्याएँ बिना quotes या दशमलव बिंदु के जाती हैं। Python उन्हें integers कहती है। वे उतनी बड़ी हो सकती हैं जितनी आपको जरूरत हो; Python बिना किसी विशेष प्रयास के मनमाने रूप से बड़ी संख्याएँ संभालती है।

python
score      = 0
age        = 28
population = 8_100_000_000   # अंडरस्कोर केवल पठनीयता के लिए हैं

Integers बिना quotes या दशमलव बिंदुओं के लिखे जाते हैं। Python integers arbitrary precision के हैं: वे किसी भी मान को रखने के लिए बढ़ते हैं, C या Java में 32- या 64-bit fixed-size integers के विपरीत। numeric literals में अंडरस्कोर सौंदर्यशास्त्र के लिए हैं और Python द्वारा अनदेखा किए जाते हैं।

python
score      = 0
age        = 28
population = 8_100_000_000

Python में int arbitrary-precision है: object मान बढ़ने पर अतिरिक्त मेमोरी आवंटित करता है, केवल उपलब्ध RAM द्वारा सीमित। CPython -5 से 256 तक के छोटे integers को singletons के रूप में cache करता है; id(1) == id(1) हमेशा True है। उस सीमा के बाहर, प्रत्येक literal एक अलग object बनाता है। इसीलिए integer comparisons के लिए is अविश्वसनीय परिणाम देता है; हमेशा == का उपयोग करें।

python
score      = 0
age        = 28
population = 8_100_000_000

दशमलव संख्याएँ (float)

दशमलव बिंदु वाली कोई भी संख्या float है। वे अधिकांश गणनाओं के लिए अपेक्षित रूप से काम करती हैं। एक बात जाननी चाहिए: कुछ दशमलव मानों को binary में ठीक से संग्रहीत नहीं किया जा सकता, इसलिए आपको एक छोटी सी rounding error मिल सकती है:

python
price       = 4.99
temperature = 36.6

0.1 + 0.2   # 0.30000000000000004

रोज़मर्रा के काम के लिए यह शायद ही कभी मायने रखता है। वित्तीय गणनाओं के लिए जहाँ पैसे के अंश मायने रखते हैं, Python में एक decimal module है जो इसे सही तरीके से संभालता है। यह Numbers अध्याय में शामिल है।

दशमलव बिंदु वाली कोई भी संख्या float बन जाती है। Python floats IEEE 754 binary64 हैं: लगभग 15-17 significant decimal digits की precision के साथ 64 bits। प्रसिद्ध समस्या: 0.1 + 0.2 है 0.30000000000000004। Python की कोई bug नहीं; binary representation का परिणाम। वित्तीय गणनाओं के लिए जहाँ exact decimals मायने रखते हैं, Python का decimal module सही tool है, जो Numbers अध्याय में शामिल है।

python
price       = 4.99
temperature = 36.6

float C के double से map होता है: IEEE 754 binary64, 53-bit mantissa, 2^-52 ≈ 2.2e-16 की relative precision। वे भिन्न जिनके denominators में 2 के अलावा अन्य prime factors हैं (जैसे 1/10 = 1/(2×5)) binary में non-terminating हैं और ठीक से संग्रहीत नहीं किए जा सकते। सटीक decimal arithmetic के लिए, Python का decimal.Decimal arbitrary-precision base-10 का उपयोग करता है। सटीक rational arithmetic के लिए, fractions.Fraction numerator/denominator pairs संग्रहीत करता है। दोनों standard library में हैं, Modules अध्याय में शामिल हैं।

python
price       = 4.99
temperature = 36.6

सच या झूठ (bool)

कुछ चीज़ें बस चालू या बंद होती हैं। Python इसके लिए booleans का उपयोग करती है: ठीक दो मान, True और False। वे इस चरण में मामूली लगते हैं, लेकिन आपके प्रोग्राम में हर condition और branch एक boolean पर चलती है।

python
is_logged_in = True
has_errors   = False

Python कुछ मानों को भी False की तरह मानती है जब उन्हें किसी condition में उपयोग किया जाता है: 0, 0.0, "", और None (Python का "यहाँ कोई मान नहीं") सभी False की तरह व्यवहार करते हैं। बाकी सब True की तरह व्यवहार करते हैं। यह Control flow अध्याय में उपयोगी हो जाता है।

bool ठीक True या False रखता है। यह comparisons द्वारा लौटाया जाता है और conditions द्वारा उपभोग किया जाता है। Python में truthy और falsy मानों का एक व्यापक सेट है: शून्य मान, खाली containers, और None falsy हैं; बाकी सब truthy हैं। एक उपयोगी विवरण: bool int का subclass है, इसलिए True + True का मूल्यांकन 2 होता है।

python
is_logged_in = True
has_errors   = False

bool int को subclass करता है। True और False क्रमशः integer मान 1 और 0 वाले singletons हैं। Falsy मान: शून्य मान (0, 0.0), खाली sequences और mappings ("", [], (), {}), None, और False। बाकी सब truthy है। Custom objects __bool__ या __len__ के माध्यम से इसे नियंत्रित करते हैं। isinstance(True, int) True है, जो generic type-checking code में मायने रखता है।

python
is_logged_in = True
has_errors   = False

प्रकार जाँचना और बदलना

जब आप निश्चित नहीं हों कि कोई मान किस प्रकार का है, type() आपको बताता है। यह जाँचने के लिए कि कोई मान किसी विशिष्ट प्रकार का है, isinstance() अधिक विश्वसनीय tool है:

python
print(type("hello"))   # <class 'str'>
print(type(42))        # <class 'int'>
print(type(3.14))      # <class 'float'>
print(type(True))      # <class 'bool'>

isinstance(42, int)    # True
isinstance("hi", str)  # True

type() किसी object का सटीक प्रकार लौटाता है। अपने कोड में type checking के लिए, isinstance() बेहतर है: यह inheritance को संभालता है, जो type() comparisons नहीं करते।

python
print(type(42))          # <class 'int'>
isinstance(True, int)    # True   (bool, int का subclass है)
type(True) == int        # False  (केवल exact match, कोई subclass नहीं)

type(x) x के लिए type object लौटाता है। isinstance(x, T) MRO (x.__class__.__mro__) को traverse करता है, subclass relationships को संभालता है जो type() comparisons चूक जाते हैं। व्यावहारिक मामला: isinstance(True, int) True है क्योंकि bool int को subclass करता है; type(True) == int False है क्योंकि यह एक exact identity check है। production code में type guards के लिए isinstance() का उपयोग करें।

python
isinstance(True, int)    # True
type(True) == int        # False

Python प्रकारों को स्वचालित रूप से नहीं मिलाती। एक string और एक number को concatenate करने पर TypeError होता है:

python
score = 42
print("आपका स्कोर है " + score)        # TypeError
print("आपका स्कोर है " + str(score))   # काम करता है

प्रकार नाम को function के रूप में उपयोग करके स्पष्ट रूप से रूपांतरित करें:

कॉलपरिणाम
str(42)"42"
int(3.9)3 (truncate करता है, round नहीं)
float("3.14")3.14
int("3.14")ValueError: decimal string को सीधे int में नहीं बदल सकते
int(float("3.14"))3 (पहले float में बदलें, फिर int में)
bool(0) / bool("")False

व्यवहार में

एक छोटी स्क्रिप्ट में सभी चार प्रकार एक साथ काम कर रहे हैं। output पंक्तियाँ पाठ में मानों को embed करने के लिए f-strings का उपयोग करती हैं: opening quote से पहले f लगाएँ और किसी भी वेरिएबल को {} में लपेटें। Python इसे वेरिएबल के वास्तविक मान से बदल देती है। आप उन्हें अगले अध्याय में ठीक से सीखेंगे।

python
player_name = "अर्जुन"
level       = 3
accuracy    = 0.94
is_premium  = True

print(f"{player_name} स्तर {level} पर है, {accuracy:.0%} सटीकता के साथ।")
print(f"प्रीमियम खाता: {is_premium}")

प्रकार मायने रखते हैं क्योंकि level + 1 काम करता है और player_name + 1 नहीं करता। प्रत्येक वेरिएबल ठीक एक प्रकार की चीज़ रखता है; Python उन्हें आपके लिए चुपचाप नहीं मिलाएगी।

सभी चार प्रकारों के साथ एक realistic config block, constants को runtime state से अलग किया गया। f"..." syntax एक f-string है: {} के अंदर कोई भी expression रनटाइम पर evaluate किया जाता है और output में embed किया जाता है। Output and input अध्याय में पूरी तरह से शामिल है।

python
BASE_URL    = "https://api.example.com"
MAX_RETRIES = 3
DEBUG       = False

user_name     = "अर्जुन"
request_count = 0
last_response = None

request_count += 1
print(f"[{request_count}] {BASE_URL} | debug={DEBUG}")

None "अभी तक कोई मान नहीं" के लिए मानक placeholder है। इसका प्रकार NoneType है और यह conditions में falsy की तरह व्यवहार करता है। उन वेरिएबल के लिए default के रूप में इसका उपयोग करें जो प्रोग्राम में बाद तक अर्थपूर्ण नहीं होते।

Inline type annotations के साथ वही config। Annotations type checkers और IDEs के लिए documentation हैं; उनका रनटाइम पर कोई प्रभाव नहीं होता:

python
BASE_URL:    str  = "https://api.example.com"
MAX_RETRIES: int  = 3
DEBUG:       bool = False

user_name:     str        = "अर्जुन"
request_count: int        = 0
last_response: str | None = None

str | None Python 3.10 से union syntax है: वेरिएबल या तो string या None रखता है। पुराने versions में, समकक्ष typing module से Optional[str] है। आधुनिक Python में str | None form बेहतर है जब minimum version इसकी अनुमति देता है।