Executie (Python)

Uit De Vliegende Brigade
Ga naar: navigatie, zoeken

Interactief

De verschillende executables die ik heb voor Python (okt. 2019) in /usr/bin. Dit is de locatie waar de shebang naar verwijst. De link python3 verwijst trouwens naar python3.5 - Dat is dus mijn default-python3-versie

Zoals veel geïnterpreteerde programmertalen, kent Python twee modussen: Interactief en gescript. Veel programmeertalen hebben echte beperkingen tot wat je kunt doen in interactieve modus. Ik heb de indruk dat Python daar veel gemakkelijker in is: Alsof je een heel programma commando-voor-commando interactief kunt uitvoeren ('s kijken hoe dat gaat rondom flow control!). Da's superhandig tijdens debuggen.

Afhankelijk van welke versie(s) van Python je hebt geïnstalleerd (en of die naast elkaar zijn geïnstalleerd), kun je de interactieve modus aanroepen met bv.:

python 
python2
python3
python3.5
python3.7

Ik heb een alias aangemaakt voor python3 in .bashrc: alias p3="python3".

Scripts

Expliciete aanroep met Python

Indien je scripts aanroept met het commando python, dan hoeven scripts niet executeerbaar te zijn (chmod +x <bestandsnaam>). Je hebt ook geen shebang nodig. Voorbeelden:

# Python 2:
#
python <bestandsnaam>

# Ook Python 2:
#
python2 <bestandsnaam>

# Python 3:
#
python3 <bestandsnaam>

# Python 3 - met alias in .bashrc:
#
p3 <bestandsnaam>

Voorbeeld van zo'n script zonder shebang:

# Als je een Python-script aanroept met "Python <bestandsnaam>",
# dan heb je geen shebang nodig...
#
print("Hello world! Ik ben een script zonder shebang")

Als generiek executeerbaar script

Een aanroep met Python is eigenlijk maar vreemd. Ik vind het logischer als ik Python-scripts kan aanroepen zoals dat normaal gaat bij executeerbare programma's (PHP is hierop een uitzondering, maar PHP is dan ook niet bedoeld als gewone scripttaal, maar specifiek voor executie door een webserver). En dat kan:

  • Maak het bestand uitvoerbaar: chmod +x <bestandsnaam>
  • Voeg shebang in op de eerste regel.

Er is nog een reden waarom deze manier van uitvoering logischer is: Nu bepaalt het script welke versie van Python gebruikt wordt, en niet de uitvoerder.

Aanroep: Gewoon de bestandsnaam, zoals voor alle executeerbare bestanden. Dat kan vanaf de terminal, maar ook bv. vanuit Nautilus. Alleen de optie execute script in browser valt me wat tegen: Er lijkt nix te gebeuren. Sois.

Shebangs

Python 2:

#!/ usr/bin/python

Python 3:

#!/ usr/bin/python3

Met of zonder extentie?

  • De gebruikelijke extentie voor Python-scripts, is .py - Zowel voor Python2 als Python3
  • Op Linux hoef je geen extentie te gebruiken, maar op Windows is het noodzakelijk. Wel of niet doen? → Boeit niet.

Interpreter takes precedence over shebang

Je hoeft óf de interpreter te benoemen, óf een shebang in te voegen. Als je allebei gebruikt, krijgt de interpreter precedence. Dit is een reële situatie bij interactie-na-executie (zie elders).

Voorbeeld:

Als ik dit bestand

#! /usr/bin/python3.7
#
import sys
print (sys.version)

uitvoer met python3 test.py krijg ik als uitvoer

3.5.2 (default, Jul 10 2019, 11:58:48) 
[GCC 5.4.0 20160609]

en als ik het uitvoer met python3.7 test.py, krijg ik

3.7.4 (default, Jul 24 2019, 08:59:57) 
[GCC 5.4.0 20160609]

Interactief ná script

Normaal als je een script uitvoert, heb je naderhand geen toegang tot de objecten of variabelen in dat script. Dat is echter wel mogelijk met de -i-flag. Da's heel handig voor oa. debuggen en ontwikkelen.

Dit werkt echter alleen als je een script aanroept met python -i <bestandsnaam>. Dan krijg je dus de rare situatie dat je expliciet de interpreter benoemt én dat er (doorgaans?) een shebang is.

Voorbeeld:

Bestand timestamp.py:

#! /usr/bin/python3
#
# Timestamp
#############################################################################
#
import time
import datetime
time_stamp=datetime.datetime.fromtimestamp(time.time()).strftime('%Y%m%d-%H%M')

print(time_stamp)

Vanaf een terminal:

Srompf@dell2016:/home/strompf/Dropbox/O&O/PyBasic$ p3 -i ./timestamp.py 
20190731-1838
>>> print(time_stamp)
20190731-1838
>>> 

Deze manier van aanroepen kan niet zonder de expliciete aanroep van Python: Anders zou de flag geassociëerd worden met het te starten script.

Zie ook