Skip to content
Snippets Groups Projects
Commit d1a86424 authored by Rafael László's avatar Rafael László :speech_balloon:
Browse files

update class chapter

parent 30325694
No related branches found
No related tags found
No related merge requests found
# Scope és Osztály
<Note type="tip" label>
**TL;DR Tartalom**
- [Osztályok](#osztályok) - Ízelítő az osztályokról
- [Elnevezések](#elnevezések) - snake_case, UpperCaseCamelCase
- [Scope](#scope) - általánosságban
- [Built-in Namespace - Beépített névtér](#built-in-namespace---beépített-névtér) -
bárhol elérhető objektumok
- [Global Namespace - Globális névtér](#global-namespace---globális-névtér) -
Modulon belül elérhető objektumok
- [Local Namespace - Lokális névtér](#local-namespace---lokális-névtér) -
Lokálisan, függvény példák, katalógus
- [Python osztály](#python-osztály) - Felépítés,
példák, init és dunder metódusok
- [Láthatóság](#láthatóság) - \_ -al privátnak tekintjük
- [Öröklés](#öröklés) - Keres a megadott ősosztályokban,
"minden `virtual`"
</Note>
<Note label>
**Extra feladatok**
_Ezek nem kötelező feladatok, csak megoldásuk közben könyebb
megtanulni a dolgokat_
- Készíts osztályokat a kutyáknak, macskáknak és a
medvéknek úgy, hogy ezeknek legyen ősosztálya és
a legtöbb közös tulajdonságot reprezentálja.
</Note>
## Osztályok
Az osztályok egy lehetőséget biztosítanak, hogy
......@@ -27,11 +60,14 @@ Pythonban a függvényeinket és változásainkat szokás
minden betű kisbetűs és a szóköz helyett `_`-k vannak.
Osztályainkat pedig `UpperCaseCamelCase` írjuk, azaz
egybe, nagy betűvel kezdve és minden új szót nagy betűvel kezdve
egybe, és minden szó kezdő betűjét nagy betűvel
szóköz nélkül.
## Scope
Ahhoz, hogy megértsük, hogy hogyan tudunk egy objektumhoz
adatot hozzá csatolni, meg kell értsük a Scope-okat is.
A Python folyamatosan menedzseli a jelenleg kezelt neveket
és hozzájuk tartozó objektumokat.
Egy katalógusként tudod ezt az egészet elképzelni.
......@@ -62,18 +98,18 @@ a python. Tehát ha belül definiálunk egy változót,
az csak azon a funkción belül lesz elérhető.
```python
>>> def my_function():
>>> def fv():
... a = 3
... if a == 1:
... b=2
... print(a)
... print(b)
...
>>> my_function()
>>> fv()
3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in my_function
File "<stdin>", line 6, in fv
UnboundLocalError: local variable 'b' referenced before assignment
```
......@@ -83,18 +119,18 @@ létezik, viszont nem kapott értéket és emiatt Error-t kaptunk.
Például egy nem létező változóval:
```python
def my_function2():
def fv2():
... a = 3
... if a == 1:
... b=2
... print(a)
... print(not_existing_variable)
...
>>> my_function2()
>>> fv2()
3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in my_function2
File "<stdin>", line 6, in fv2
NameError: name 'not_existing_variable' is not defined
```
......@@ -109,7 +145,7 @@ kapott is.
## Python osztály
A szintaxis:
Na és akkor nézzük meg, hogy hogyan néz ki egy osztály.
```python
class OsztalyNev:
......@@ -118,10 +154,10 @@ class OsztalyNev:
.
```
Például egy egyszerű osztály:
Hogy legyen is benne valami:
```python
>>> class MyClass:
>>> class Osztalyom:
... """A simple example class""" # Dokumentáció
... i = 12345
... def f(self):
......@@ -132,45 +168,57 @@ Például egy egyszerű osztály:
Ebből tudunk egy példányt készíteni:
```python
>>> x = MyClass()
>>> x = Osztalyom()
>>> x.i
12345
```
Viszont jelenleg még nincs konstruktorunk.
Ezt az **init** függvény definiálásával tudjuk javítani.
Ilyenkor meghívtuk az alapértelmezett konstruktorát.
Ha saját konstruktort szeretnénk, akkor a beépített
**\_\_init\_\_** függvényt tudjuk felhasználni.
A különböző objektumainknak megannyi ilyen beépített
függvénye van egyébként.
Például felültudjuk írni, hogy mi történjen,
ha az objektumot összeszorozzuk valamivel,
vagy mit írjon ki ha simán ki Printeljük és így tovább.
_Ezeket Double Underscore, azaz "Dunder" metódusoknak
hívják_
[Részletesebben](https://docs.python.org/3/reference/datamodel.html)
```python
>>> class MyClass:
... """A simple example class"""
>>> class Osztalyom:
... """Egy példa osztály"""
... i = 12345 # Minden objektum által megosztott
... def f(self):
... return 'hello world'
... def __init__(self):
... def __init__(self): #
... self.data = []
```
Az első paraméterünk az a jelenlegi objektumra mutat.
Tehát amit ehhez hozzáírunk az csak az adott
objektumban lesz benne.
Egy érdekes különbség C-től, hogy a változóinkat
nem definiáljuk kötvetlen, hanem az init metódusában
vesszük fel őket.
Ha ezt nem így tennénk, akkor valójában egy statikus
minden objektum közt megosztott változót készítenénk.
A konstruktor metódusunkban feltűnhet az első paraméter.
Ez az a változó, mely a jelenleg létrejövő objektumra mutat.
Ha ehhez hozzáírunk új adatokat, akkor csak abban lesz benne.
```python
>>> class Complex:
... def __init__(self, realpart, imagpart):
... self.r = realpart
... self.i = imagpart
>>> class Komplex:
... def __init__(self, valos, imaginarius):
... self.r = valos
... self.i = imaginarius
...
>>> x = Complex(3.0, -4.5)
>>> x = Komplex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)
```
Osztályunkban definiált változókat megosztják a belőle
készített objektumok.
Ezért figyelni kell rá, hogy ne definiáljunk `mutable`
változókat az `__init__`-en kívül, ugyanis ezek értékéhez
bármely objektum hozzáfér onnantól.
Példa:
Statikus változóval ilyesmi problémába üzközhetünk bele:
```python
class Dog:
......@@ -215,10 +263,11 @@ class Dog:
Erre a magyarázat, hogy ezekre az objektumokra csak mutatók
készülnek.
Tehát mikor mi definiáltuk az osztályunk akkor készítettünk
egy új listát `[]`, melynek a mutatóját a tricks-re
állítottuk.
Mikor ebből új objektumokat képeztünk, akkor ugyanazokat
a mutató értékeket kapták az egyes leszármazottak.
egy új listát `[]`, majd pedig a trickset rámutattuk a
listánkra.
Ezt követően mikor ebből új objektumokat képeztünk,
akkor ugyanazokat a mutató értékeket kapták az egyes
leszármazottak.
## Láthatóság
......@@ -226,23 +275,28 @@ Pythonban az osztályokban a tagváltozók és függvények
publikusan elérhetőek és nem lehet őket priváttá tenni.
Erre egy konvenció, hogyha `_`-al kezdődik a nevük, akkor
privátként kezeljük őket.
Ekkor nem lesznek privátak, ugyanúgy publikok maradnak,
viszont ha valaki hozzányúl a kódhoz, akkor nem fogja
ezeket használni, legfeljebb Getter, Setteren keresztül.
```python
class Visibility:
def __init__(self, private_info):
self._private_info = private_info
class Lathatosag:
def __init__(self, privat_info):
self.privat_info = privat_info
def get_private_info(self):
return self._private_info
def get_privat_info(self):
return self.privat_info
def set_private_info(self, new_value):
self._private_info = new_value
def set_privat_info(self, uj_ertek):
self.privat_info = uj_ertek
```
## Öröklés
Szintaxis:
Talán az egyik legbonyolultabbnak ható témakör,
viszont Pythonban hidd el, hogy nagyon egyszerűen
működik.
```python
class Osztály(Ősosztály1, Ősosztály2, ...):
......@@ -251,9 +305,12 @@ class Osztály(Ősosztály1, Ősosztály2, ...):
.
```
Az osztály megjegyzi az ősosztályait és mikor
hivatkozunk egy attributumára, de nem találjuk, akkor
ellenőrzésre kerül az ősosztályban is.
Ilyenkor az osztályunk elmenti az összes ősosztályát,
majd pedig ha hivatkozni próbálunk benne valamire,
akkor sorban ellenőrzi először az Osztály-ban, majd
pedig az Ősosztályokban, hogy hol található meg.
Ha nem található, akkor meg a szokásos hibával tér vissza.
Tehát C++-ra gondolva például minden függvényünk `virtual`.
Ha szeretnénk az ősosztály konstruktorát meghívni, akkor
a `super` kulcsszót tudjuk használni.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment