logo

Mutató Pythonban | Miért nem támogatja a Python a mutatót?

Ebben az oktatóanyagban megismerjük a mutatót a Pythonban, és megtudjuk, hogy a Python miért nem támogatja a pointer fogalmakat.

Azt is megértjük, hogyan szimulálhatjuk a mutatót Pythonban. Az alábbiakban bemutatjuk a mutatót azoknak, akik nem tudnak róla.

Azt is megértjük, hogyan szimulálhatjuk a mutatót Pythonban. Az alábbiakban bemutatjuk a pointer bevezetését azoknak, akik nem értenek hozzá.

Mi az a Pointer?

A mutató egy nagyon népszerű és hasznos eszköz a változó címének tárolására. Ha valaki dolgozott már olyan alacsony szintű nyelvvel, mint pl C . C++ , valószínűleg ismeri a mutatókat. Nagyon hatékonyan kezeli a kódot. Kezdők számára kissé nehéz lehet, de ez a program egyik fontos koncepciója. Ez azonban különféle memóriakezelési hibákhoz vezethet. Így a mutatók meghatározása -

„A mutatók azok a változók, amelyek egy másik változó memóriacímét tárolják. A mutatóváltozókat csillag (*) jelöli.'

Nézzük a következő példát a mutatóra C programozási nyelvben.

Példa – Hogyan használjuk a mutatót C-ben

 #include int main() { int* po, o; 0 = 10; printf('Address of c: %p
', &c); printf('Value of c: %d

', c); o = &0; printf('Address of pointer pc: %p
', o); printf('Content of pointer pc: %d

', *o); 0 = 11; printf('Address of pointer pc: %p
', p0); printf('Content of pointer pc: %d

', *p0); *po = 2; printf('Address of c: %p
', &o); printf('Value of c: %d

', o); return 0; } 

Kimenet:

Address of o: 2686784 Value of o: 22 Address of pointer po: 2686784 Content of pointer po: 22 Address of pointer po: 2686784 Content of pointer po: 11 Address of o: 2686784 Value of o: 2 

Amellett, hogy hasznosak, a mutatókat nem használják Piton . Ebben a témakörben a Python objektummodelljét tárgyaljuk, és megtudjuk, miért nem léteznek mutatók a Pythonban. Megtanuljuk a mutatók Pythonban való szimulálásának különböző módjait is. Először is beszéljük meg, hogy a Python miért nem támogatja a mutatókat.

Miért nem támogatja a Python a mutatókat?

A mutató nem támogatott pontos oka nem világos. Létezhet-e natív pointer a Pythonban? A Python fő koncepciója az egyszerűsége, de a mutató megsértette a A Python Zene. A mutatók elsősorban implicit változtatások, nem pedig explicit változtatások. Komplexek is, különösen kezdőknek.

A mutatók általában bonyolultabbá teszik a kódot, ahol a Python elsősorban a használhatóságra összpontosít, nem pedig a sebességre. Ennek eredményeként a Python nem támogatja a mutatót. A Python azonban bizonyos előnyöket nyújt a mutató használatából.

Mielőtt megértené a mutatót Pythonban, ismernünk kell a következő pontokat.

  • Változatlan vs. változtatható objektumok
  • Python változók/nevek

Objektumok Pythonban

A Pythonban minden egy objektum, még osztályok, függvények, változók stb. Minden objektum legalább három adatot tartalmaz.

java rendezési karakterláncok
  • Referenciaszám
  • típus
  • Érték

Beszéljük meg egyenként.

Hivatkozási szám - Memóriakezelésre használják. A Python memóriakezelésével kapcsolatos további információkért olvassa el a Memóriakezelés Pythonban című részt.

Típus - A CPython réteget használjuk típusként, hogy megbizonyosodjunk a típusbiztonságról futás közben. Végül van egy érték, amely az objektumhoz tartozó tényleges érték.

Ha mélyebbre megyünk ebben az objektumban, azt fogjuk látni, hogy nem minden objektum egyforma. Az objektumok típusai közötti fontos különbség a megváltoztathatatlan és változtatható. Először is meg kell értenünk a különbséget az objektumok típusai között, mivel a Pythonban lévő mutatót vizsgálja.

Változatlan vs. változtatható objektumok

A megváltoztathatatlan objektumok nem módosíthatók, míg a változtatható objektumok módosíthatók. Nézzük meg a következő táblázatot a gyakori típusokról, és arról, hogy változtathatók-e vagy sem.

Objektumok típus
Int Változhatatlan
Úszó Változhatatlan
Bool Változhatatlan
Lista Változékony
Készlet Változékony
Összetett Változékony
Tuple Változhatatlan
Frozenset Változhatatlan
Dict Változékony

A fenti objektumok típusát a segítségével ellenőrizhetjük id() módszer. Ez a módszer az objektum memóriacímét adja vissza.

loop bash számára

Az alábbi sorokat REPL környezetben írjuk be.

 x = 5 id(x) 

Kimenet:

140720979625920 

A fenti kódban az x-hez 10 értéket rendeltünk. ha ezt az értéket helyettesítéssel módosítanánk, akkor az új objektumokat kapnánk.

 x-=1 id(x) 

Kimenet:

140720979625888 

Amint látjuk, módosítjuk a fenti kódot, és válaszként új objektumokat kapunk. Vegyünk egy másik példát str .

 s = 'java' print(id(s)) s += 'Tpoint' print(s) id(s) 

Kimenet:

2315970974512 JavaTpoint 1977728175088 

Ismét módosítjuk az x értékét egy új karakterlánc hozzáadásával, és megkapjuk az új memóriacímet. Próbáljuk meg közvetlenül hozzáadni a stringet az s-ben.

 s = 'java' s[0] = T print(id(s)) 

Kimenet:

Traceback (most recent call last): File 'C:/Users/DEVANSH SHARMA/PycharmProjects/MyPythonProject/python1.py', line 34, in s[0] = T NameError: name 'T' is not defined 

A fenti kód hibát ad vissza, ez azt jelenti, hogy a karakterlánc nem támogatja a mutációt. Így str a megváltoztathatatlan tárgyak.

Most látni fogjuk a változtatható objektumot, például a listát.

 my_list = [3, 4, 8] print(id(my_list)) my_list.append(4) print(my_list) print(id(my_list)) 

Kimenet:

2571132658944 [3, 4, 8, 4] 2571132658944 

Ahogy a fenti kódban láthatjuk, a a listám eredeti azonosítója van, és a listához 5-tel fűztük; a listám ugyanaz az azonosítója, mert a lista támogatja a változékonyság.

A Python-változók megértése

A változók Pythonban való definiálásának módja nagyban különbözik a C-től vagy a C++-tól. A Python változó nem határozza meg az adattípust. Valójában a Pythonnak nevei vannak, nem változói.

Tehát meg kell értenünk a változók és nevek közötti különbséget, és ez különösen igaz, ha a Python mutatóinak trükkös témájában navigálunk.

Nézzük meg, hogyan működik a változó C-ben, és hogyan működik a név Pythonban.

Változók C-ben

A C nyelvben a változó az, hogy értéket vagy tárolási értéket tartalmaz. Az adattípussal van meghatározva. Lássuk a következő kódot, amely meghatározza a változót.

 int x = 286; 
  • Foglaljon le elegendő memóriát egy egész szám számára.
  • Ehhez a memóriahelyhez a 286 értéket rendeljük.
  • Az x ezt az értéket jelenti.

Ha az emlékezet nézetét képviseljük -

Mutató Pythonban

Amint látjuk, az x-nek van egy memóriahelye a 286-os értékhez. Most az új értéket rendeljük x-hez.

x = 250

Ez az új érték felülírja az előző értéket. Ez azt jelenti, hogy az x változó változtatható.

formázza meg a dátumot java-ban

Az x érték helye ugyanaz, de az érték megváltozott. Ez egy fontos pont, amely jelzi, hogy x a memóriahely, nem csak a neve.

Most bemutatjuk az új változót, amely átveszi az x-et, majd az y létrehozza az új memóriadobozt.

 int y = x; 

Az y változó új dobozt hoz létre, y bemásolja az x értékét a dobozba.

Mutató Pythonban

Nevek Pythonban

Amint azt korábban tárgyaltuk, a Python nem rendelkezik a változókkal. Nevei vannak, és ezt a kifejezést használjuk változóként. De van különbség a változók és a nevek között. Lássuk a következő példát.

 x = 289 

A fenti kód lebontásra kerül a végrehajtás során.

  1. Hozzon létre egy PyObject-et
  2. Állítsa be a PyObject típuskódját egész számra
  3. Állítsa a PyObject értékét 289-re
  4. Hozzon létre egy x nevű nevet
  5. Mutasson x-et az új PyObjectre
  6. Növelje a PyObject újraszámlálását 1-gyel

Az alábbiak szerint fog kinézni.

Mutató Pythonban

Megérthetjük egy változó belső működését a Pythonban. Az x változó az objektum referenciájára mutat, és nem rendelkezik a korábbi memóriaterülettel. Azt is mutatja, hogy az x = 289 az x nevet hivatkozáshoz köti.

Most új változót vezetünk be, és x-et rendelünk hozzá.

 y = x 

Pythonban az y változó nem hozza létre az új objektumot; ez csak egy új név, amely ugyanarra az objektumra mutat. A tárgy visszaszámlálás szintén eggyel nőtt. Ezt a következőképpen tudjuk megerősíteni.

 y is x 

Kimenet:

True 

Ha y értékét eggyel növeljük, az már nem ugyanarra az objektumra fog hivatkozni.

 y + =1 y is x 

Ez azt jelenti, hogy Pythonban nem rendelünk hozzá változókat. Ehelyett a neveket hivatkozásokhoz kötjük.

Mutatók szimulálása Pythonban

Ahogy már megbeszéltük, a Python nem támogatja a mutatót, de kihasználhatjuk a mutató használatának előnyeit. A Python alternatív módokat kínál a mutató használatára a Pythonban. Ezt a két módot az alábbiakban mutatjuk be.

  • Mutabilis típusok használata mutatóként
  • Egyéni Python objektumok használata

Értsük meg a megadott pontokat.

Változó típusok használata mutatóként

Az előző részben definiáltuk a változó típusú objektumokat; kezelhetjük őket úgy, mintha mutatók lennének a mutató viselkedésének szimulálására. Értsük meg a következő példát.

C

 void add_one(int *a) { *a += 1; } 

A fenti kódban *a mutatót definiáltunk, majd az értéket eggyel növeljük. Most a main() függvénnyel fogjuk megvalósítani.

list.sort java
 #include int main(void) { int y = 233; printf('y = %d
', y); add_one(&y); printf('y = %d
', y); return 0; } 

Kimenet:

y = 233 y = 234 

Ezt a fajta viselkedést szimulálhatjuk a Python-változó típus használatával. Értse meg a következő példát.

 def add_one(x): x[0] += 1 y = [2337] add_one(y) y[0] 

A fenti függvény eléri a lista első elemét, és eggyel növeli az értékét. Amikor a fenti programot végrehajtjuk, kiírja az y módosított értékét. Ez azt jelenti, hogy a mutatót a mutálható objektum segítségével replikálhatjuk. De ha megpróbáljuk szimulálni a mutatót megváltoztathatatlan objektum segítségével.

 z = (2337,) add_one(z) 

Kimenet:

Traceback (most recent call last): File '', line 1, in File '', line 2, in add_one TypeError: 'tuple' object does not support item assignment 

A fenti kódban a tuple-t, egy megváltoztathatatlan objektumot használtuk, így a hibát adta vissza. A szótár segítségével a mutatót Pythonban is szimulálhatjuk.

Értsük meg a következő példát, ahol a programban előforduló összes műveletet megszámoljuk. Ezt a diktátumot használhatjuk.

Példa -

 count = {'funcCalls': 0} def car(): count['funcCalls'] += 1 def foo(): count['funCcalls'] += 1 car() foo() count['funcCalls'] 

Kimenet:

2 

Magyarázat -

A fenti példában a számol szótár, amely nyomon követte a függvényhívások számát. Amikor az foo() függvény meghívása esetén a számláló 2-vel nő, mert a dict változtatható.

Python objektumok használata

Az előző példában a dict parancsot használtuk a mutató emulálására Pythonban, de néha nehéz megjegyezni az összes használt kulcsnevet. A szótár helyett használhatjuk a Python egyéni osztályt. Értsük meg a következő példát.

Példa -

 class Pointer(object): def __init__(self): self._metrics = { 'funCalls': 0, 'catPictures': 0, } 

A fenti kódban definiáltuk a Pointer osztályt. Ez az osztály a dict-ot használta a tényleges adatok tárolására a _metrics tagváltozóban. Ez biztosítja a programunk megváltoztathatóságát. Ezt a következőképpen tehetjük meg.

 class Pointer(object): # ... @property def funCalls(self): return self._metrics['func_calls'] @property def catPictures_served(self): return self._metrics['cat_pictures_served'] 

használtunk @ingatlan lakberendező. Ha nem ismeri a lakberendezőket, látogassa meg Python dekorátor oktatóanyagunkat. A @property lakberendező hozzáférhet a funCalls és a catPicture_served szolgáltatásokhoz. Most létrehozunk egy objektumot a Pointer osztályból.

 pt = Pointer() pt.funCalls() pt.catPicture_served 

Itt növelnünk kell ezeket az értékeket.

 class Pointer(object): # ... def increament(self): self._metrices['funCalls'] += 1 def cat_pics(self): self._metrices['catPictures_served'] += 1 

Két új metódust definiáltunk: increment() és cat_pics(). Az értékeket ezen függvények segítségével módosítottuk a mátrixokban. Itt ugyanúgy megváltoztathatjuk az osztályt, mint a mutatót.

 pt = Pointer() pt.increment() pt.increment() pt.funCalls() 

Python ctypes modul

A Python ctypes modul lehetővé teszi, hogy C-típusú mutatót hozzunk létre Pythonban. Ez a modul akkor hasznos, ha függvényhívást akarunk végrehajtani egy mutatót igénylő C könyvtárba. Értsük meg a következő példát.

Példa - C nyelv

 void incr_one(int *x) { *x += 1; } 

A fenti függvényben az x értékét eggyel növeltük. Tegyük fel, hogy elmentjük a fenti incrPointer.c nevű fájlt és a következő parancsot a terminálba.

 $ gcc -c -Wall -Werror -fpic incrPointer.c $ gcc -shared -o libinc.so incrPointer.o 

Az első parancs lefordítja incrPointer.c nevű tárgyba incrPointer.o. A második parancs elfogadja az objektumfájlt és létrehozza a libinic.so-t a ctype-okkal való együttműködéshez.

különbség a tömb és a tömblista között
 import ctypes ## libinc.so library should be same directory as this program lib = ctypes.CDLL('./libinc.so') lib.increment 

Kimenet:

 

A fenti kódban a ctypes.CDLL nevű megosztott objektumot ad vissza libinikus.úgy. Ez tartalmazza a incrPointer() funkció. Ha meg kell adnunk a mutatót a megosztott objektumban definiált függvényekre, akkor azt a ctypes segítségével kell megadnunk. Lássuk az alábbi példát.

 inc = lib.increment ## defining the argtypes inc.argtypes = [ctypes.POINTER(ctypes.c_int)] 

Ha a függvényt más típussal hívjuk meg, akkor az hiba lép fel.

 incrPointer(10) 

Kimenet:

Traceback (most recent call last): File '', line 1, in ctypes.ArgumentError: argument 1: : expected LP_c_int instance instead of int 

Ennek az az oka, hogy az incrPointer mutatót igényel, a ctypes pedig a mutató átadásának módja a Pythonban.

 v = ctypes.c_int(10) 

v egy C változó. A ctypes az ún byref() amely korábban átadta a változó hivatkozást.

 inc(ctypes.byref(a)) a 

Kimenet:

c_int(11) 

Az értéket a referenciaváltozó segítségével növeltük.

Következtetés

Megbeszéltük, hogy a mutató nincs jelen a Pythonban, de ugyanezt a viselkedést megvalósíthatjuk a *mutable objektummal. Megvitattuk azokat a ctypes modulokat is, amelyek képesek C-mutatót definiálni a Pythonban. Meghatároztunk néhány kiváló módszert a mutató szimulálására Pythonban.