Python (programozási nyelv)

A Wikipédiából, a szabad enciklopédiából
A lap korábbi változatát látod, amilyen Lucianvince (vitalap | szerkesztései) 2021. május 28., 12:44-kor történt szerkesztése után volt. Ez a változat jelentősen eltérhet az aktuális változattól. (→‎Szabványos könyvtárak: hozzáadott egy megbízható forrást a Python könyvtárakhoz, amelyet más programozási nyelvekkel összefüggésben magyaráztak a jobb megértés érdekében.)
Python

Paradigmatöbbelvű
Jellemző kiterjesztés.py, .pyw, .pyc, .pyo, .pyd
Megjelent1991. február 20.
TervezőGuido van Rossum
Fejlesztő
Utolsó kiadás
Típusosságerős, dinamikus
FordítóprogramCPython, Jython, IronPython, PyPy
MegvalósításokCPython, IronPython, Jython, Python for S60, PyPy
Hatással volt ráABC, C, Haskell, Icon, Lisp, Modula-3, Perl, Smalltalk, Tcl
Befolyásolt nyelvekRuby, Boo
Operációs rendszerplatformfüggetlen
LicencPython Software Foundation Licenc
Weboldal


A Python egy általános célú, nagyon magas szintű programozási nyelv,[2] melyet Guido van Rossum holland programozó kezdett el fejleszteni 1989 végén, majd hozott nyilvánosságra 1991-ben.[3] A nyelv tervezési filozófiája az olvashatóságot és a programozói munka megkönnyítését helyezi előtérbe a futási sebességgel szemben.[4][5]

A Python többek között a funkcionális, az objektumorientált, az imperatív és a procedurális programozási paradigmákat támogatja. Dinamikus típusokat és automatikus memóriakezelést használ, ilyen szempontból hasonlít a Scheme, Perl és Ruby nyelvekhez, emellett szigorú típusrendszerrel rendelkezik.

A Python úgynevezett interpreteres nyelv, ami azt jelenti, hogy nincs különválasztva a forrás- és tárgykód, a megírt program máris futtatható, ha rendelkezünk a Python értelmezővel. A Python értelmezőt számos géptípusra és operációs rendszerre elkészítették, továbbá számtalan kiegészítő könyvtár készült hozzá, így rendkívül széles körben használhatóvá vált.

Története

A Python alapötlete az 1980-as évek végén született meg.[6] A fejlesztést 1989 decemberében kezdte el Guido van Rossum a CWI-n.[7] A CWI (Centrum Wiskunde & Informatica, magyarul Matematikai és Informatikai Központ) egy kutatóintézet Amszterdamban. A nyelv a nevét a Monty Python csoportról kapta.[8] 1991 februárjában jelent meg az első nyilvános változat (0.9.0 verzió néven) az alt.sources hírcsoportban.[9] 1994-ben jött létre a comp.lang.python hírcsoport, ami egy jelentős mérföldkő volt a nyelv fejlődésében.[6] Szintén 1994-ben látott napvilágot az 1.0 verzió, amit az ezredfordulón, 2000 októberében követett a Python 2.0, majd pedig 2008-ban a Python 3.0.[10]

Egyszerű adattípusok

A Python különbséget tesz a mutálható és a mutálhatatlan típusok között. Ezek a fogalmak első közelítésben a megváltoztathatóságra utalnak, ám a pontos különbség ennél finomabb.[11][12]

A Python 3 beépített típusai
típus leírás példa
str
Unicode string
'Wikipédia'
"Wikipédia"
"""Több
soros
string"""
bytearray
Bájtok (mutálható) sorozata.
bytearray(b'Some ASCII')
bytearray(b"ASCII karakterek")
bytearray([119, 105, 107, 105])
bytes
Bájtok (mutálhatatlan) sorozata.
b'ASCII karakterek'
b"ASCII karakterek"
bytes([119, 105, 107, 105])
list
List típus, ami eltérő típusokat is tartalmazhat, azaz nem tipizált lista.
[4.0, 'string', True]
tuple
Rendezett n-es.
(4.0, 'string', True)
set
frozenset
Rendezetlen halmaz adattípusok. Duplikátumokat nem tartalmazhatnak.

Nem tipizáltak, azaz eltérő típusú elemeket is tartalmazhatnak, ha azok hasíthatóak.

{4.0, 'string', True}
frozenset([4.0, 'string', True])
dict
Hasítótábla, más néven szótár vagy asszociatív tömb adattípus.

Kulcs-érték párokat tartalmazhat. A kulcsoknak hasíthatónak kell lenniük.

{'key1': 1.0, 3: False}
int
Tetszőleges méretű egész szám adattípus.
42
float
Lebegőpontos szám, melynek pontossága az implementáló rendszertől függ.
3.1415927
complex
komplex szám adattípus valós és képzetes résszel.
3+2.7j
bool
Kétértékű logikai adattípus.
True
False

Kivételkezelés

A kivételkezelés a try kulcsszóval történik. Például így:

try:
    f()
except (NameError,TypeError):
    print('Az f függvény végrehajtása során NameError vagy TypeError lépett fel.')
except Exception:
    print('Nem várt kivétel lépett fel.')
else:
    print('Semmilyen kivétel nem lépett fel.')
finally:
    print('Ez a mondat mindenképp kiíródik.')

Ha olyan kivétel lép fel a try blokkban, ami valamely except ágban szerepel, akkor a vezérlés az illető except ágnak adódik át. Egy except ág több kivételtípust is kezelhet, az egyes kivételtípusokat vesszővel elválasztva lehet megadni.

Az except ág lefutása után a try blokk utáni részen folytatódik a program. Ha nem lép fel semmilyen kivétel, akkor a vezérlés az else ágra kerül a lefutás után, ha az létezik. Mindig csak egy except ág fut le. Ha az utolsó except ág nem ad meg kivételtípust, akkor az kezeli az összes olyan kivételt, amit a megelőző ágak nem kezeltek. Végül szerepelhet egy opcionális finally blokk, ami mindenképpen lefut.

Ha nincs megfelelő except ág, akkor továbbadódik a kivétel a tartalmazó blokknak. Az except ágakban fellépő kivételek szintén a tartalmazó blokknak adódnak át. Ha egyáltalán nincs try blokk, például egy függvényben, akkor minden kivétel a tartalmazó blokknak adódik át.

def hibas_fuggveny():
    x=1/0
try:
    hibas_fuggveny()
except ZeroDivisionError as ex:
    print('Nullával osztás.', ex)

A nyelv tartalmaz beépített kivételeket, de a lehetőség van saját kivételeket definiálására is. A kivételek paraméterezhetőek, típusuktól függően más és más paraméterük lehet. Kivétel kiváltására a raise kulcsszó alkalmazható:

raise NameError('Hello')

Osztályok, öröklődés

A Python osztálymechanizmusának tervezésénél a szempont az volt, hogy minimális szintaktikai és szemantikai újdonságokat vezessenek be. C++ és a Modula-3 osztálymechanizmusának a keveréke. Többszörös öröklődésre is lehetőséget ad, a származtatott osztály átdefiniálhatja az ősosztálya(inak) metódusait, egy metódus hívhatja az ősosztály metódusát ugyanazon a néven. Az objektumok tartalmazhatnak nem publikusnak szánt adatokat, azonban maga a nyelv semmi biztosítékot nem nyújt arra, hogy hívó fél is valóban így fogja kezelni.[13] A tagváltozó vagy tagfüggvényt kezdhetjük egy aláhúzással, ezzel jelezvén, hogy ezt nem publikusnak szánjuk (gyakorlatilag a protected, package-private vagy privát láthatóságot szánjuk az adott tagnak).

class MyObject(object):
    def __init__(self, name):
        self._name = name   # Jelezzük, hogy ez egy protected vagy package-private adat
                            # nem szeretnénk, ha direktben használná bárki
                            # kivéve a csomagot, amiben van/leszármazott osztályokat

myobj = MyObject("Ez a nevem")
print(myobj._name) # De ez csak egy jelzés, kívülről ugyanúgy elérhető, mint bármely más adat

Különbségek a C++-hoz képest, hogy az osztály- és objektumváltozók publikusak (kivéve a dupla aláhúzással kezdődőeket, amik egy speciális mechanizmusnak köszönhetően megóvhatják a kódunkat például az öröklődéskor előforduló névfelüldefiniálásoktól[13]), és minden tagfüggvény virtuális.

A Python a szokásos értelemben nem használ konstruktor és destruktor függvényeket, de a nem kötelezően definiálandó, speciális "__init__" és "__del__" tagfüggvényeket a rendszer az objektumpéldány létrehozásakor, illetve az objektum explicit törlésekor ("del" utasítás) vagy amikor a szemétgyűjtő (garbage collector) felszabadítja a tárhelyet, automatikusan meghívja. Az "__init__"-et nagyon gyakran használják az tagváltozók kezdeti értékadására:

class MyObject(object):
    def __init__(self, name):
        self.name = name

myobj = MyObject("Ez a nevem")
print(myobj.name) # Kiírja, hogy "Ez a nevem"

Az osztályok maguk is objektumok – valójában a Pythonban minden adattípus objektum. A 2.2-es verziótól kezdve a beépített típusokat is bővítheti a felhasználó. Minden operátor felüldefiniálható speciális nevű tagfüggvényekben. (Például az összeadás operátor (+) a "__add__", "__radd__", "__ladd__" segítségével, a szorzás operátor (*) a "__mul__", "__rmul__", "__lmul__" segítségével, stb.)

Ugyanarra az objektumra több néven is lehet hivatkozni, objektumok esetében értékadás alapértelmezés szerint referenciát (hivatkozást) jelent, nem új objektumpéldány létrehozását.

Osztálydefiníció:

class ClassName(object):
    <statement-1>
    ...
    <statement-N>

#Például:
class MyClass(object):
    "Egy egyszerű példa osztály"
    i = 42
    def f(self):
        return 'hello world!'

Az osztálynak mielőtt hatása lenne, a vezérlésnek rá kell futnia az osztálydefinícióra, így akár egy if-ágban is lehet osztálydefiníció. Az osztály-objektum az osztálydefiníció végén automatikusan létrejön. Példányosítani az osztály nevével, valamint a paraméterlista megadásával tudunk. Üres paraméterlistát is jeleznünk kell (nem úgy, mint C++-ban), egy üres zárójel-párral, különben az osztály referenciáját másoljuk egy változóba. (pl.: x = MyClass() ). Az objektumok tagváltozóit nem az osztálydefinícióban deklaráljuk, hanem az objektum inicializálására használt "__init__" metódusban, hiszen ezek így lokálisan, adott objektumpéldányra lesznek érvényesek, míg az osztálydefinícióban deklarált változók az egész osztályra (így bármely objektumára is) érvényesek lesznek.

Azonban azt is megtehetjük, hogy egy adat attribútumot később deklarálunk, mely az használatkor jön létre. Példa:

class MyObject(object):
    i = 42  # összes objektumpéldányra érvényes változó
            # (hasonlít a hagyományos statikus változókhoz, de nem teljesen ugyanaz a működése)
    def __init__(self):
        self.counter = 0  # objektum inicializáláskor létrehozunk egy tagváltozót
 
ctr = MyObject()
ctr.counter += 10  # módosítjuk a tagváltozó értékét

print(ctr.counter)  # 10
print(ctr.i)  # 42

ctr.anotherCounter = 0  # deklarálunk egy új adattagot az adott objektumba
print(ctr.anotherCounter)  # 0

MyObject.i = 100  # Az osztályban lévő i változót módosítjuk
anotherOne = MyObject()  # Létrehozunk egy másik objektumpéldányt
print(anotherOne.i)  # 100
print(ctr.i)  # 100
# print(ctr.anotherCounter)  # ebben az objektumban nincs ilyen tagváltozó

A del utasítással megszüntethetünk bármilyen változót, akár objektum-tagváltozót is.

class MyObject(object):
    def __init__(self):
        self.counter = 0

ctr = MyObject()
ctr.counter += 10
print(ctr.counter)  # 10
del ctr.counter
# print(ctr.counter) # itt már nincs ilyen tagváltozónk

Egy másik példa

def MyClass(object):
    i = 42
    def f(self):
        return 'hello world!'

x = MyClass()
x.counter = 1
while x.counter < 10:
    x.counter = x.counter * 2
print(x.counter)
del x.counter

Ez a kis példa 16-ot ír ki (nem a legegyszerűbb módon), és semmilyen nyoma nem marad az osztályban, hiszen a del utasítással töröltük a létrehozott counter nevű változót.

Ügyeljünk rá, hogy x.f nem ugyanaz, mint MyClass.f, mivel az első az hivatkozás az adott objektum egy tagfüggvényére (metódus típusú objektumra való hivatkozás), amely hivatkozás futás közben megváltozhat (tehát például más metódusra mutat), míg a MyClass.f a f függvény prototípusa, ezáltal függvény típusú objektumra való hivatkozás! x.f egy metódus objektum, nem függvényobjektum. x.f() – ki fogja írni: hello world. Ugyanis az objektum, mint első argumentum átadódik a függvénynek, azaz x.f() ekvivalens MyClass.f(x) -szel.

További megjegyzések:

  • az adat attribútumok felülírják az ugyanolyan nevű metódus attribútumot! Ezért célszerű valamilyen névkonvencióval kizárni az ilyen lehetőséget.
  • nincs lehetőség az adatelrejtésre – az adat attribútumokat éppúgy elérik a metódusok, mint az objektum kliensei.
  • az előbbi lehetővé teszi, hogy kliensek elrontsák az invariánst, ha meglévő adat attribútumot írnak felül. Ezt a programozónak kell megoldania, mivel a nyelv nem nyújt rá lehetőséget.
  • ha létezik egy __init__() metódusa az osztálynak, akkor példányosításkor az objektum létrehozása után meghívódik, átadva a példányosításkor esetleg megadott paramétereket:
class Alma(object):
    def __init__(self, szin, iz):
        self.szin = szin
        self.iz = iz
 
x = Alma("piros", "savanyu")

A Python lehetőséget nyújt a többszörös öröklődésre, melynek szintaxisa az alábbiak szerint néz ki:

class DerivedClassName([modulename.]Base1[,[[modulename.]Base2,]):
    <statement-1>
    ...
    <statement-N>

Ha egy hivatkozást nem talál az aktuális osztályban, akkor Base1-ben keresi,ha Base1-ben sincs, akkor Base1 őseiben. Ezután ha még mindig nem találta, akkor Base2-ben kezdi el keresni, és így tovább.

Rekord vagy struct-szerű objektumok létrehozására is van lehetőség, a már ismertetettek szerint, például egy üres osztály deklarálásával, majd az üres osztály egy példányát feltölthetjük:

 class Dolgozo:
    pass        # ez egy üres osztálydefiníció
 
 John = Dolgozo()
 John.nev = 'John Cosinus'
 John.osztaly = 'Matematikai reszleg'
 John.fizetes = 42000

Azonban, ha ilyen céljaink vannak, sokkal inkább ajánlott a szótár (asszociatív tömb) használata, hogy feleslegesen ne terheljük az interpretert ilyen dummy osztályok, majd abból keletkező objektumok létrehozásával:

dolgozok = list()

John = {'nev': 'John Cosinus',
      'osztaly': 'Matematikai részleg',
      'fizetes': 42000}
dolgozok.append(John)

Jason = dict()
Jason['nev'] = 'Jason Cosinus'
Jason['osztaly'] = 'Matematikai reszleg'
Jason['fizetes'] = 42000
dolgozok.append(Jason)

A kivételek korábban lehettek egyszerű string objektumok, azonban Python 3-ban csak és kizárólag a "BaseException" osztály, vagy leszármazottjának egy példánya lehet.

Forma: raise instance. Egy except klóz kompatibilis a kivétellel, ha ugyanabban az osztályban vannak vagy a kivétel az elkapni kívánt típus leszármazottja. Példa:

class B:
    pass
class C(B):
    pass
class D(C):
    pass
 
for c in [B,C,D]:
    try:
        raise c()
    except D:
        print("D")
    except C:
        print("C")
    except B:
        print("B")

Az eredmény B,C,D ebben a sorrendben. Ha azonban az except ágakat fordítva írtuk volna, akkor az eredmény B,B,B lett volna, mert a legelső illeszkedő except-ág aktivizálódik.

Szabványos könyvtárak

A Pythonnak igen kiterjedt és széles körű standard könyvtára van, amit még kiegészítenek az egyéb (mások által megírt) publikus modulok[14]. A standard könyvtár adattípusokat (például számokat és listákat) tartalmaz, amelyeket egyébként a nyelv magjának tekintenek. Tartalmaz még beépített függvényeket és kivételeket, melyeket használni lehet import nélkül, viszont a legnagyobb rész természetesen modulokban van. A modulok egy részét C-ben írták meg, és beépítették az interpreterbe, másokat Python forráskódban kell importálni.

Ismertebb Pythonra épülő alkalmazások

A LAMP tartalmazza a Pythont is
  • a Zope alkalmazáskiszolgáló
  • ill. a Zope-ra épülő Plone tartalomkezelő-rendszer (CMS)
  • Mailman levelezési listakezelő
  • Trac projekt-kezelő rendszer
  • a kéretlen reklámleveleket kiszűrő SpamBayes
  • az egyik leghíresebb fájlcserélő szoftver, a BitTorrent eredeti implementációja
  • A Blender 3D modellező-animációs program, ami ezért GE-ként is működik, Pythonból scriptelhető

Jegyzetek

  1. a b Python 3.12.3 and 3.13.0a6 released (angol nyelven), 2024. április 9. (Hozzáférés: 2024. április 9.)
  2. General Python FAQ. python.org. Python Software Foundation. (Hozzáférés: 2009. június 27.)
  3. General Python FAQ. Python Programming Language – Official Website. Python Software Foundation. (Hozzáférés: 2010. március 16.)
  4. What is Python Good For?. General Python FAQ. Python Software Foundation. (Hozzáférés: 2008. szeptember 5.)
  5. What is Python? Executive Summary. Python documentation. Python Software Foundation. (Hozzáférés: 2007. március 21.)
  6. a b The Making of Python. Artima Developer. (Hozzáférés: 2007. március 22.)
  7. A Brief Timeline of Python. Guido van Rossum. (Hozzáférés: 2009. január 20.)
  8. http://docs.python.org/2/faq/general.html#why-is-it-called-python
  9. HISTORY. Python source distribution. Python Foundation. [2016. február 17-i dátummal az eredetiből archiválva]. (Hozzáférés: 2007. március 21.)
  10. http://www.python.org/download/releases
  11. Python Documentation - 3. Data Types. (Hozzáférés: 2013. október 7.)
  12. Immutable vs mutable types - Python. (Hozzáférés: 2013. október 7.)
  13. a b 9. Classes — Python 3.7.0 documentation. docs.python.org. (Hozzáférés: 2018. szeptember 1.)
  14. Node.js vs Python: Which backend technology to choose in 2021? (amerikai angol nyelven). Insights on Latest Technologies - Simform Blog, 2021. február 19. (Hozzáférés: 2021. május 28.)

További információk

Commons:Category:Python (programming language)
A Wikimédia Commons tartalmaz Python (programozási nyelv) témájú médiaállományokat.

Kapcsolódó szócikkek