क्

क्लास में Python

49 अभ्यास

क्लास के बारे में

Classes डेटा को व्यवहार के साथ जोड़ती हैं। क्लास का उपयोग डेटा और व्यवहार के बंडल की प्रतियाँ या instances बनाने के लिए किया जाता है, जिन्हें आमतौर पर objects कहा जाता है। ऑब्जेक्ट वास्तविक दुनिया की चीज़ों (जैसे कार या बिल्लियाँ) को दर्शा सकते हैं, या अधिक अमूर्त अवधारणाओं (जैसे पूर्णांक, वाहन या स्तनधारी) को। क्लास ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग (OOP) दृष्टिकोण का अभिन्न हिस्सा हैं। यह दृष्टिकोण प्रोग्रामर से कहता है कि वह किसी समस्या को एक या अधिक ऑब्जेक्ट के रूप में सोचे। ये ऑब्जेक्ट आपस में क्रिया करते हैं, स्थिति बनाए रखते हैं और डेटा पर काम करते हैं।

क्लास

क्लास नए ऑब्जेक्ट टाइप की परिभाषाएँ हैं, और इन्हीं से ऑब्जेक्ट के नए instances बनाए जाते हैं। ये अक्सर डेटा (जिसे fields, attributes, properties, data members या variables कहा जाता है) को उस कोड या फंक्शन (जिन्हें methods कहा जाता है) के साथ रखती हैं जो उस डेटा पर काम करते हैं। इस अर्थ में क्लास एक खाका या निर्देशों का ऐसा समूह है, जिससे एक जैसे टाइप के कई ऑब्जेक्ट बनाए और इस्तेमाल किए जा सकते हैं। एक जटिल प्रोग्राम में कई क्लास हो सकती हैं, और हर क्लास कई अलग-अलग तरह के ऑब्जेक्ट बनाती है। किसी क्लास से ऑब्जेक्ट बनाने और उसे अपनी ज़रूरत के अनुसार ढालने की प्रक्रिया को instantiation (या क्लास का इंस्टेंस बनाना) कहा जाता है।

Python में क्लास की परिभाषा सीधी-सादी होती है:

class MyClass:
    # Class body goes here

क्लास एट्रिब्यूट

क्लास फील्ड (जिन्हें प्रॉपर्टी, एट्रिब्यूट, डेटा मेंबर या वेरिएबल भी कहा जाता है) को क्लास के अंदर जोड़ा जा सकता है।

class MyClass:
    number = 5
    string = "Hello!"

MyClass का एक इंस्टेंस (ऑब्जेक्ट) बनाकर किसी नाम से बाँधा जा सकता है:

>>> new_object = MyClass()

# Class is instantiated and resulting object is bound to the "new_object" name (variable).
# Note: the object address 'at 0x15adc55b0' will vary by computer.
>>> new_object
<__main__.MyClass at 0x15adc55b0>

किसी क्लास से बने सभी ऑब्जेक्ट (या इंस्टेंस) में Class attributes साझा होते हैं। इन्हें dot notation से एक्सेस किया जा सकता है, यानी ऑब्जेक्ट के नाम के बाद और एट्रिब्यूट के नाम से पहले एक . लगाकर:

>>> new_object = MyClass()

# Accessing the class attribute "number" via dot-notation.
>>> new_object.number
5

# Accessing the class attribute "string" via dot-notation.
>>> new_object.string
'Hello!'

# Instantiating an additional object and binding it to the "second_new_object" name.
>>> second_new_object = MyClass()

>>> second_new_object
<__main__.MyClass at 0x15ad99970>

# Second_new_object shares the same class attributes as new_object.
>>> new_object.number == second_new_object.number
True

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

>>> obj_one = MyClass()
>>> obj_two = MyClass()

# Accessing a class attribute from an object.
>>> obj_two.number
5

# Accessing the class attribute from the class itself.
>>> MyClass.number
5

# Modifying the value of the "number" class attribute.
>>> MyClass.number = 27

# Modifying the "number" class attribute changes the "number" attribute for all objects.
>>> obj_one.number
27

>>> obj_two.number
27

हर समय एक जैसा डेटा रखने वाले ढेर सारे ऑब्जेक्ट होना खास उपयोगी नहीं है। अच्छी बात यह है कि किसी क्लास से बने ऑब्जेक्ट को उसके अपने instance attributes (या इंस्टेंस प्रॉपर्टी, वेरिएबल या फील्ड) के ज़रिए अपनी ज़रूरत के अनुसार ढाला जा सकता है। जैसा कि नाम से पता चलता है, इंस्टेंस एट्रिब्यूट हर ऑब्जेक्ट के लिए अलग होते हैं और इन्हें स्वतंत्र रूप से बदला जा सकता है।

__init__() के साथ ऑब्जेक्ट इंस्टैंशिएशन को अपने अनुसार ढालना

विशेष "डंडर मेथड" (यानी "डबल अंडरस्कोर मेथड" का छोटा रूप) __init__() का उपयोग क्लास के इंस्टेंस को अपनी ज़रूरत के अनुसार ढालने के लिए किया जाता है, और इससे ऑब्जेक्ट के इंस्टेंस एट्रिब्यूट या प्रॉपर्टी को इनिशियलाइज़ किया जा सकता है। इंस्टेंस एट्रिब्यूट को इनिशियलाइज़ करने की भूमिका के कारण __init__() को class constructor या initializer भी कहा जाता है। __init__() एक ज़रूरी पैरामीटर लेता है जिसका नाम self है, और यह नए बने ऑब्जेक्ट को दर्शाता है। इसके बाद इंस्टेंस एट्रिब्यूट या प्रॉपर्टी के लिए डेटा, self पैरामीटर के बाद __init__() के आर्गुमेंट के रूप में भेजा जा सकता है।

नीचे दिए उदाहरण में MyClass में अब location_x और location_y नाम के इंस्टेंस एट्रिब्यूट हैं। जैसा कि आप देख सकते हैं, इन दोनों एट्रिब्यूट को __init__() को भेजे गए location (जो एक टपल है) आर्गुमेंट के पहले और दूसरे इंडेक्स पर असाइन किया गया है। अब जब आप क्लास को इंस्टैंशिएट करते हैं और एक ऑब्जेक्ट बनता है, तो क्लास के इंस्टेंस के location_x और location_y एट्रिब्यूट इनिशियलाइज़ हो जाते हैं:

class MyClass:
    # These are class attributes, variables, or fields.
    number = 5
    string = "Hello!"

    # This is the class "constructor", with a "location" parameter that is a tuple.
    def __init__(self, location):

        # This is an instance or object property, attribute, or variable.
        # Note that we are unpacking the tuple argument into two separate instance variables.
        self.location_x = location[0]
        self.location_y = location[1]

# Create a new object "new_object_one", with object property (1, 2).
>>> new_object_one = MyClass((1, 2))

# Create a second new object "new_object_two" with object property (-8, -9).
>>> new_object_two = MyClass((-8, -9))

# Note that new_object_one.location_x and new_object_two.location_x two different values.
>>> new_object_one.location_x
1

>>> new_object_two.location_x
-8

ध्यान दीजिए कि ऊपर MyClass को इनिशियलाइज़ करते समय आपको केवल एक आर्गुमेंट भेजना है। क्लास को कॉल करने पर self भेजने का काम Python खुद कर लेता है।

Advanced

इंस्टेंस वेरिएबल बनाने का एक और तरीका है: किसी ऑब्जेक्ट के ज़रिए क्लास वेरिएबल को सीधे एक्सेस करके उसे कुछ और बदल देना:

>>> obj_one = MyClass()
>>> obj_two = MyClass()
>>> MyClass.string
'Hello!'

>>> obj_two.string = "Hi!"
>>> obj_two.string
'Hi!'

>>> obj_one.string
'Hello!'

अब देखिए कि क्लास वेरिएबल बदलने पर क्या होता है:

>>> MyClass.string = "World!"
>>> obj_two.string

# obj_two.string has not changed
'Hi!'

>>> obj_one.string

# obj_one.string changed
'World!'

obj_two के मामले में string एट्रिब्यूट अब एक इंस्टेंस वेरिएबल है, लेकिन obj_one में यह क्लास वेरिएबल ही रहता है।

यह क्लास के अंदर से भी किया जा सकता है:

class Demo:
    new_var = 3

    def add_two(self):
        self.new_var += 2

जिस पल <object>.add_two() को कॉल किया जाता है और self.new_var += 2 पढ़ा जाता है, new_var क्लास वेरिएबल से उसी नाम के इंस्टेंस वेरिएबल में बदल जाता है।

यह इनिशियलाइज़ेशन के दौरान तब काम आ सकता है जब क्लास के सभी इंस्टेंस को शुरू में एक ही वैल्यू वाले कुछ एट्रिब्यूट चाहिए हों। लेकिन तब इंस्टेंस वेरिएबल क्लास वेरिएबल को छाया में डाल देता है, जिससे जहाँ छाया पड़ी है वहाँ से क्लास वेरिएबल एक्सेस नहीं किया जा सकता। ऐसी स्थिति में इंस्टेंस एट्रिब्यूट को __init__() मेथड से self.<attribute> के रूप में सेट करना ज़्यादा सुरक्षित और साफ़ हो सकता है।

मेथड

एक method ऐसा function है जो या तो क्लास से ही बँधा होता है (जिसे क्लास मेथड कहा जाता है, और आगे के किसी अभ्यास में इस पर विस्तार से चर्चा होगी) या क्लास के इंस्टेंस (ऑब्जेक्ट) से। ऑब्जेक्ट या इंस्टेंस पर काम करने वाले मेथड को पहले पैरामीटर के रूप में self के साथ बनाना ज़रूरी है। इसके बाद बाकी पैरामीटर आप वैसे ही बना सकते हैं जैसे किसी "सामान्य" या अनबाउंड फंक्शन के लिए बनाते हैं। क्लास पर काम करने वाले मेथड को @classmethod डेकोरेटर के साथ और (परंपरा के अनुसार) पहले पैरामीटर के रूप में cls के साथ बनाना ज़रूरी है। क्लास मेथड को क्लास पर सीधे कॉल किया जाता है, क्लास से पहले ऑब्जेक्ट बनाए बिना।

class MyClass:
    number = 5
    string = "Hello!"

    # Class constructor.
    def __init__(self, location):

        # Instance properties
        self.location_x = location[0]
        self.location_y = location[1]

    # Class method. Uses the @classmethod decorator, and cls as the first parameter.
    # Can be called without first making an instance of the class.
    @classmethod
    def change_string(cls, new_string):
        #Class attributes are referred to with cls.
        cls.string = new_string
        return cls.string

    # Instance method.  Note "self" as first parameter.
    def change_location(self, amount):
        self.location_x += amount
        self.location_y += amount
        return self.location_x, self.location_y

एट्रिब्यूट की तरह ही मेथड को कॉल करना भी उतना ही आसान है: ऑब्जेक्ट के नाम के बाद और मेथड के नाम से पहले एक . लगाइए। कॉल किए गए मेथड को पहले पैरामीटर के रूप में ऑब्जेक्ट की प्रति की ज़रूरत नहीं होती। Python खुद self भर देता है:

class MyClass:
    number = 5
    string = "Hello!"

    def __init__(self, location):
        self.location_x = location[0]
        self.location_y = location[1]

    def change_location(self, amount):
        self.location_x += amount
        self.location_y += amount
        return self.location_x, self.location_y

# Make a new test_object with location (3,7)
>>> test_object = MyClass((3,7))
>>> (test_object.location_x, test_object.location_y)
(3,7)

# Call change_location to increase location_x and location_y by 7.
>>> test_object.change_location(7)
(10, 14)

क्लास एट्रिब्यूट को इंस्टेंस मेथड के अंदर से भी उसी तरह एक्सेस किया जा सकता है जैसे क्लास के बाहर किया जाता है:

class MyClass:
    number = 5
    string = "Hello!"

    def __init__(self, location):
        self.location_x = location[0]
        self.location_y = location[1]

    # Alter instance variable location_x and location_y
    def change_location(self, amount):
        self.location_x += amount
        self.location_y += amount
        return self.location_x, self.location_y

    # Alter class variable number for all instances from within an instance.
    def increment_number(self):
        # Increment the 'number' class variable by 1.
        MyClass.number += 1


>>> test_object_one = MyClass((0,0))
>>> test_object_one.number
5

>>> test_object_two = MyClass((13, -3))
>>> test_object_two.increment_number()
>>> test_object_one.number
6

pass के साथ कार्यान्वयन को फिलहाल खाली छोड़ना

पिछले कॉन्सेप्ट अभ्यासों और प्रैक्टिस अभ्यास के स्टब में आपने देखा होगा कि फंक्शन के अंदर असली कोड की जगह pass कीवर्ड का उपयोग किया गया है।

pass कीवर्ड एक सिंटैक्स के हिसाब से मान्य प्लेसहोल्डर है। यह खाली फंक्शन या क्लास परिभाषा के लिए Python को सिंटैक्स एरर देने से रोकता है। मूल रूप से यह Python इंटरप्रेटर से कहने का तरीका है, "चिंता मत कीजिए! मैं यहाँ कोड ज़रूर डालूँगा, बस अभी तक नहीं डाला।"

class MyClass:
    number = 5
    string = "Hello!"

    def __init__(self, location):
        self.location_x = location[0]
        self.location_y = location[1]

    # Alter instance variable location_x and location_y.
    def change_location(self, amount):
        self.location_x += amount
        self.location_y += amount
        return  self.location_x, self.location_y

    # Alter class variable number for all instances.
    def increment_number(self):
        # Increment the 'number' class variable by 1.
        MyClass.number += 1

    # This will compile and run without error, but has no current functionality.
    def pending_functionality(self):
       # Stubbing or place-holding the body of this method.
       pass
GitHub के ज़रिए संपादित करें यह लिंक नई विंडो या टैब में खुलता है।

क्लास सीखिए

अभ्यास लॉक है

क्लास पर अभ्यास करने के लिए 6 और अभ्यास अनलॉक कीजिए