Kurzusok
/
Python
Python
/
Tanterv
/
Osztályok
Os

Osztályok ebben a kurzusban: Python

49 feladat

A(z) Osztályok fogalomról

Az Classes adatot és viselkedést kapcsolnak össze. Az osztályokkal másolatokat vagy instances-okat hozunk létre összekapcsolt adatokból és viselkedésből, amelyeket általában objects néven ismerünk. Az objektumok ábrázolhatnak valós világbeli entitásokat (például autókat vagy macskákat), vagy elvontabb fogalmakat (például egészeket, járműveket vagy emlősöket). Az osztályok szerves részét képezik az objektumorientált programozás (OOP) szemléletmódjának, amely arra kéri a programozót, hogy a problémát egy vagy több objektumként modellezze: ezek kölcsönhatásba lépnek egymással, állapotot tartanak fenn, és hatnak az adatokra.

Osztályok

Az osztályok új objektumtípusok definíciói, és belőlük jönnek létre az objektumok új instances-ai. Gyakran adatokat (amelyeket fields, attributes, properties, data members vagy variables néven ismerünk) kapcsolnak össze olyan kóddal vagy függvényekkel (amelyeket methods néven ismerünk), amelyek ezeken az adatokon működnek. Ebben az értelemben az osztály egy tervrajz, illetve utasítások halmaza, amelyből sok hasonló típusú objektum építhető fel és használható. Egy összetett program sok osztályból állhat, és mindegyik sokféle objektumot épít fel. Az objektum osztályból történő felépítésének és testreszabásának folyamatát instantiation-nak (vagyis az osztály egy példányának létrehozásának) nevezik.

Egy osztály definiálása Pythonban egyszerű:

class MyClass:
    # Class body goes here

Osztályattribútumok

Az osztálymezők (más néven tulajdonságok, attribútumok, adattagok vagy változók) hozzáadhatók az osztály törzséhez.

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

A MyClass egy példánya (objektuma) létrehozható és egy névhez köthető:

>>> 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>

A Class attributes minden, egy osztályból létrehozott objektum (vagy példány) között megosztott, és a dot notation segítségével érhető el, ami egy . az objektum neve után, közvetlenül az attribútum neve előtt:

>>> 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

Az osztályattribútumokat magának az osztálynak a törzsében definiáljuk, minden más metódus előtt. Az osztály birtokolja őket, ezért megoszthatók a példányok között. Mivel ezeket az attribútumokat az osztály minden példánya megosztja, értékük közvetlenül az osztályból is elérhető és módosítható. Az osztályattribútumok értékének megváltoztatása az osztályból példányosított összes objektum értékét megváltoztatja:

>>> 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

Nem túl hasznos, ha egy csomó objektum adatai mindig szinkronban vannak. Szerencsére az osztályból létrehozott objektumok testre szabhatók a saját instance attributes-szal (vagy példánytulajdonságokkal, -változókkal vagy -mezőkkel). Ahogy a nevük is sugallja, a példányattribútumok minden objektumnál egyediek, és egymástól függetlenül módosíthatók.

Az objektumpéldányosítás testreszabása a __init__() segítségével

A speciális „dunder method” (a „double underscore method”, azaz a dupla aláhúzás rövidítése) __init__() metódussal szabhatjuk testre az osztálypéldányokat, és inicializálhatjuk vele az objektumok példányattribútumait vagy tulajdonságait. Mivel a példányattribútumok inicializálásában játszik szerepet, a __init__()-t class constructor-nak vagy initializer-nak is nevezik. A __init__() egyetlen kötelező paramétert vár, amelynek neve self, és az újonnan létrehozott objektumra utal. A példányattribútumok vagy tulajdonságok adatait ezután a self paraméter után adhatjuk át a __init__() argumentumaiként.

Az alábbi példában a MyClass-nak most location_x és location_y nevű példányattribútumai vannak. Mint láthatod, a két attribútum a __init__()-nak átadott location (egy tuple) argumentum első és második indexéhez lett rendelve. Egy osztálypéldány location_x és location_y attribútuma most inicializálódik, amikor példányosítod az osztályt, és létrejön egy objektum:

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

Figyeld meg, hogy a fenti MyClass inicializálásakor csak egy argumentumot kell átadnod, mert a self átadásáról a Python gondoskodik, amikor meghívod az osztályt.

Advanced

A példányváltozó létrehozásának egy másik módja, hogy egyszerűen elérsz egy osztályváltozót egy objektumon keresztül, és átállítod valami másra:

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

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

>>> obj_one.string
'Hello!'

Most figyeld meg, mi történik, amikor az osztályváltozó megváltozik:

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

# obj_two.string has not changed
'Hi!'

>>> obj_one.string

# obj_one.string changed
'World!'

A string attribútum obj_two esetében most példányváltozó, obj_one esetében viszont osztályváltozó marad.

Ezt az osztályon belülről is megtehetjük:

class Demo:
    new_var = 3

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

Abban a pillanatban, hogy meghívjuk a <object>.add_two() metódust, és kiértékelődik a self.new_var += 2, a new_var osztályváltozóból egy azonos nevű példányváltozóvá alakul.

Ez hasznos lehet inicializáláskor, amikor egy osztály minden példányának ugyanazzal az értékkel kell indulnia egy vagy több attribútum esetében. A példányváltozó azonban ekkor árnyékolja az osztályváltozót, így az osztályváltozó nem lesz elérhető abból a példányból, ahol árnyékolt. Ezt figyelembe véve biztonságosabb és világosabb lehet a példányattribútumokat a __init__() metódusból self.<attribute> formában beállítani.

Metódusok

A method olyan function, amely vagy magához az osztályhoz (ezt class method néven ismerjük, és részletesen egy későbbi feladatban tárgyaljuk), vagy az osztály egy példányához (objektumához) kötődik. Az objektumon vagy példányon működő metódusokat úgy kell definiálni, hogy az első paraméterük a self legyen. A többi paramétert ezután ugyanúgy definiálhatod, mint egy „normál”, nem kötött függvény esetében. Az osztályon működő metódusokat a @classmethod dekorátorral kell definiálni, és (a konvenció szerint) az első paraméterük a cls. Az osztálymetódusokat közvetlenül az osztályon hívjuk meg, anélkül hogy először objektumot hoznánk létre az osztályból.

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

Az attribútumok eléréséhez hasonlóan egy metódus meghívása is olyan egyszerű, hogy az objektum neve után és a metódus neve elé egy .-t írsz. A meghívott metódusnak nem kell az objektum másolatát első paraméterként megadni, a self-et a Python automatikusan kitölti:

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)

Az osztályattribútumok a példánymetódusokon belülről ugyanúgy érhetők el, ahogy az osztályon kívülről:

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

A megvalósítás helyőrzése vagy vázolása a pass segítségével

A korábbi tanulófeladatokban és a gyakorlófeladatok vázlataiban láthattad, hogy a pass kulcsszó a függvények törzsében áll a tényleges kód helyén.

A pass kulcsszó szintaktikailag érvényes helyőrző: megakadályozza, hogy a Python szintaktikai hibát dobjon egy üres függvény- vagy osztálydefiníció miatt. Lényegében így üzensz a Python értelmezőjének: „Ne aggódj! Fogok ide kódot írni, csak még nem tettem meg.”

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
Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg

Tanuld meg a(z) Osztályok fogalmat

A gyakorlás zárolva

Oldj fel még 6 feladatot, hogy gyakorolhasd a(z) Osztályok fogalmat