Mengapa orang menulis #! / Usr / bin / env python shebang di baris pertama skrip Python?


1047

Sepertinya saya suka menjalankan file yang sama tanpa garis itu.


1
Jawaban di bawah ini menyatakan bahwa itu hanyalah sebuah baris komentar. Itu tidak selalu terjadi. Saya memiliki "Halo, Dunia!" Skrip CGI (.py) yang hanya akan berjalan dan menampilkan halaman web dengan #!/usr/bin/env pythondi bagian atas.
Chakotay


Mereka mungkin berlari, tetapi tidak di lingkungan yang dimaksud
Nicholas Hamilton

18
Saya telah mengunjungi posting ini berkali-kali dalam 7 tahun karena saya kadang-kadang lupa dengan hashbang env. Salin pasta :)
BugHunterUK

Jawaban:


1083

Jika Anda memiliki beberapa versi Python yang diinstal, /usr/bin/envakan memastikan penerjemah yang digunakan adalah yang pertama di lingkungan Anda $PATH. Alternatifnya adalah dengan hardcode sesuatu seperti #!/usr/bin/python; tidak apa-apa, tapi kurang fleksibel.

Di Unix, file yang dapat dieksekusi yang dimaksudkan untuk ditafsirkan dapat menunjukkan penerjemah apa yang harus digunakan dengan memiliki #!di awal baris pertama, diikuti oleh penerjemah (dan bendera apa pun yang mungkin diperlukan).

Jika Anda berbicara tentang platform lain, tentu saja, aturan ini tidak berlaku (tetapi "garis shebang" tidak ada salahnya, dan akan membantu jika Anda pernah menyalin skrip itu ke platform dengan basis Unix, seperti Linux, Mac , dll).


267
Hanya untuk menambahkan: ini berlaku ketika Anda menjalankannya di Unix dengan menjadikannya executable ( chmod +x myscript.py) dan kemudian menjalankannya secara langsung ./myscript.py:, bukan hanya python myscript.py.
Craig McQueen

28
menggunakan envmemberikan fleksibilitas maksimum dalam hal pengguna dapat memilih juru bahasa untuk digunakan dengan mengubah PATH. Seringkali fleksibilitas ini tidak diperlukan meskipun dan downside adalah bahwa linux misalnya tidak dapat menggunakan nama skrip untuk nama proses psdan kembali ke "python". Ketika mengemas aplikasi python untuk distro misalnya saya akan menyarankan untuk tidak menggunakan env.
pixelbeat

9
pypeluncur dapat menggunakan garis shebang di Windows. Ini termasuk dalam Python 3.3 atau dapat diinstal secara independen .
jfs

6
Sebuah kata peringatan penting, nilai pengembalian env pada akhirnya berakhir. Yang tidak mungkin mempengaruhi Anda jika Anda menjalankan proses berumur pendek. Namun, saya mengalami proses sekarat dengan pesan /usr/bin/env: Key has expiredsetelah berjam-jam.
malaverdiere

4
@malaverdiere dapatkah Anda menautkan ke sumber daya apa pun yang menjelaskan perilaku kedaluwarsa ini? Saya tidak dapat menemukan mereka.
Michael

266

Itu disebut garis shebang . Sebagaimana dijelaskan oleh entri Wikipedia :

Dalam komputasi, shebang (juga disebut hashbang, hashpling, pound bang, atau crunchbang) mengacu pada karakter "#!" ketika mereka adalah dua karakter pertama dalam arahan juru bahasa sebagai baris pertama dari file teks. Dalam sistem operasi mirip Unix, program loader mengambil keberadaan dua karakter ini sebagai indikasi bahwa file tersebut adalah skrip, dan mencoba untuk mengeksekusi skrip itu menggunakan interpreter yang ditentukan oleh sisa baris pertama dalam file.

Lihat juga entri FAQ Unix .

Bahkan pada Windows, di mana garis shebang tidak menentukan penerjemah yang akan dijalankan, Anda dapat meneruskan opsi ke juru bahasa dengan menentukannya pada garis shebang. Saya merasa berguna untuk menjaga garis shebang generik dalam skrip satu kali (seperti yang saya tulis saat menjawab pertanyaan pada SO), jadi saya dapat dengan cepat mengujinya pada Windows dan ArchLinux .

The utilitas env memungkinkan Anda untuk memanggil perintah pada jalan:

Argumen yang tersisa pertama menentukan nama program yang akan dipanggil; itu dicari sesuai dengan PATHvariabel lingkungan. Argumen yang tersisa dilewatkan sebagai argumen untuk program itu.


30
Mudah ditemukan dengan Google - jika ada yang tahu kata kunci ("garis shebang" sangat penting).
Arafangion

14
Sebenarnya, penjelasan ini lebih jelas daripada referensi lain yang saya periksa di Google. Itu selalu lebih baik untuk mendapatkan 1 paragraf penjelasan yang menargetkan pertanyaan, daripada membaca seluruh manual yang membahas setiap potensi penggunaan.
Sam Goldberg

1
@Arafangion Anda mungkin akan menemukan pertanyaan ini bermanfaat. TL; DR: symbolhound.com
ulidtko

@ulidtko: Mesin pencari yang menarik, pertimbangkan untuk menulis jawaban agar pertanyaan john garcias memiliki jawaban yang lebih baik.
Arafangion

1
"Bahkan di Windows, di mana garis shebang tidak menentukan penerjemah yang akan dijalankan, Anda dapat meneruskan opsi ke penerjemah dengan menentukannya di garis shebang." Itu hanya salah; jika hal seperti itu terjadi, itu karena penerjemah itu sendiri sedang memproses garis shebang. Jika penerjemah tidak memiliki pengakuan khusus untuk garis shebang, maka tidak ada yang terjadi. Windows tidak melakukan apa pun dengan garis shebang. "Yang mungkin Anda uraikan dalam kasus ini adalah peluncur python: python.org/dev/peps/pep-0397 .
Kaz

154

Memperluas sedikit jawaban yang lain, inilah sedikit contoh bagaimana skrip baris perintah Anda bisa mendapat masalah dengan penggunaan /usr/bin/envgaris shebang yang tidak hati-hati :

$ /usr/local/bin/python -V
Python 2.6.4
$ /usr/bin/python -V
Python 2.5.1
$ cat my_script.py 
#!/usr/bin/env python
import json
print "hello, json"
$ PATH=/usr/local/bin:/usr/bin
$ ./my_script.py 
hello, json
$ PATH=/usr/bin:/usr/local/bin
$ ./my_script.py 
Traceback (most recent call last):
  File "./my_script.py", line 2, in <module>
    import json
ImportError: No module named json

Modul json tidak ada di Python 2.5.

Salah satu cara untuk mencegah masalah semacam itu adalah dengan menggunakan nama perintah python berversi yang biasanya diinstal dengan sebagian besar Python:

$ cat my_script.py 
#!/usr/bin/env python2.6
import json
print "hello, json"

Jika Anda hanya perlu membedakan antara Python 2.x dan Python 3.x, rilis terbaru Python 3 juga memberikan python3nama:

$ cat my_script.py 
#!/usr/bin/env python3
import json
print("hello, json")

27
Hmm, bukan itu yang saya dapatkan dari pos itu.
glenn jackman

1
Perbedaan antara lokal dan global. Jika which pythonkembali /usr/bin/python, jalur direktori lokal bisa sulit kode: #!/usr/bin/python. Tapi itu kurang fleksibel daripada #!/usr/bin/env pythonyang memiliki aplikasi global.
noobninja

85

Untuk menjalankan skrip python, kita perlu memberi tahu shell tiga hal:

  1. Bahwa file tersebut adalah skrip
  2. Penerjemah mana yang ingin kita jalankan skripnya
  3. Jalan penerjemah tersebut

Shebang #!mencapai (1.). Shebang dimulai dengan a #karena #karakter adalah penanda komentar dalam banyak bahasa scripting. Oleh karena itu, isi garis shebang secara otomatis diabaikan oleh penerjemah.

The envperintah menyelesaikan (2.) dan (3). Mengutip "grawity,"

Penggunaan umum dari envperintah ini adalah untuk meluncurkan penerjemah, dengan memanfaatkan fakta bahwa env akan mencari $ PATH untuk perintah yang diperintahkan untuk diluncurkan. Karena garis shebang membutuhkan jalur absolut yang harus ditentukan, dan karena lokasi berbagai penafsir (perl, bash, python) dapat sangat bervariasi, itu biasa digunakan:

#!/usr/bin/env perl  alih-alih mencoba menebak apakah itu adalah / bin / perl, / usr / bin / perl, / usr / local / bin / perl, / usr / local / pkg / perl, / fileserver / usr / bin / perl, atau / home / MrDaniel / usr / bin / perl pada sistem pengguna ...

Di sisi lain, env hampir selalu di / usr / bin / env. (Kecuali dalam kasus-kasus ketika tidak; beberapa sistem mungkin menggunakan / bin / env, tetapi itu adalah kesempatan yang cukup langka dan hanya terjadi pada sistem non-Linux.)


1
"grawity" di mana?
Pacerier

44

Mungkin pertanyaan Anda dalam pengertian ini:

Jika Anda ingin menggunakan: $python myscript.py

Anda tidak perlu saluran itu sama sekali. Sistem akan memanggil python dan kemudian python interpreter akan menjalankan skrip Anda.

Tetapi jika Anda berniat untuk menggunakan: $./myscript.py

Memanggilnya langsung seperti program normal atau skrip bash, Anda perlu menulis baris itu untuk menentukan sistem yang digunakan program untuk menjalankannya, (dan juga membuatnya dapat dieksekusi dengan chmod 755)


atau Anda dapat menulis python3 myscript.py
vijay shanker

44

The execsystem call dari kernel Linux mengerti shebangs ( #!) native

Ketika Anda melakukannya di bash:

./something

di Linux, ini memanggil execsystem call dengan path ./something.

Baris kernel ini dipanggil pada file yang diteruskan ke exec: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_script.c#L25

if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!'))

Itu membaca byte pertama file, dan membandingkannya #!.

Jika perbandingannya benar, maka seluruh baris diuraikan oleh kernel Linux, yang membuat execpanggilan lain dengan path /usr/bin/env pythondan file saat ini sebagai argumen pertama:

/usr/bin/env python /path/to/script.py

dan ini berfungsi untuk bahasa skrip apa pun yang digunakan #sebagai karakter komentar.

Dan ya, Anda dapat membuat loop tanpa batas dengan:

printf '#!/a\n' | sudo tee /a
sudo chmod +x /a
/a

Bash mengenali kesalahan:

-bash: /a: /a: bad interpreter: Too many levels of symbolic links

#! Kebetulan bisa dibaca manusia, tapi itu tidak wajib.

Jika file dimulai dengan byte yang berbeda, maka execpanggilan sistem akan menggunakan penangan yang berbeda. Handler bawaan yang paling penting adalah untuk file yang dapat dieksekusi ELF: https://github.com/torvalds/linux/blob/v4.8/fs/binfmt_elf.c#L1305 yang memeriksa byte 7f 45 4c 46(yang juga merupakan manusia dapat dibaca untuk .ELF). Mari kita konfirmasi dengan membaca 4 byte pertama /bin/ls, yang merupakan executable ELF:

head -c 4 "$(which ls)" | hd 

keluaran:

00000000  7f 45 4c 46                                       |.ELF|
00000004                                                                 

Jadi ketika kernel melihat byte-byte itu, ia mengambil file ELF, memasukkannya ke dalam memori dengan benar, dan memulai proses baru dengannya. Lihat juga: Bagaimana kernel menjalankan file biner yang dapat dieksekusi berjalan di linux?

Akhirnya, Anda dapat menambahkan penangan shebang Anda sendiri dengan binfmt_miscmekanismenya. Misalnya, Anda dapat menambahkan penangan khusus untuk .jarfile . Mekanisme ini bahkan mendukung penangan melalui ekstensi file. Aplikasi lain adalah untuk menjalankan executable dari arsitektur yang berbeda dengan QEMU .

Saya tidak berpikir POSIX menentukan shebangs: https://unix.stackexchange.com/a/346214/32558 , meskipun ia menyebutkan bagian rasional, dan dalam bentuk "jika skrip yang dapat dieksekusi didukung oleh sistem, sesuatu mungkin terjadi". macOS dan FreeBSD juga tampaknya mengimplementasikannya.

PATH motivasi pencarian

Kemungkinan, satu motivasi besar untuk keberadaan shebang adalah kenyataan bahwa di Linux, kita sering ingin menjalankan perintah PATHhanya dari :

basename-of-command

dari pada:

/full/path/to/basename-of-command

Tapi kemudian, tanpa mekanisme shebang, bagaimana Linux tahu cara meluncurkan setiap jenis file?

Hardcoding ekstensi dalam perintah:

 basename-of-command.py

atau menerapkan pencarian PATH pada setiap penerjemah:

python basename-of-command

akan menjadi suatu kemungkinan, tetapi ini memiliki masalah besar bahwa semuanya rusak jika kita pernah memutuskan untuk mengubah perintah ke bahasa lain.

Shebangs memecahkan masalah ini dengan indah.


39

Secara teknis, dalam Python, ini hanya sebuah baris komentar.

Baris ini hanya digunakan jika Anda menjalankan skrip py dari shell (dari baris perintah). Ini dikenal sebagai " Shebang !" , dan digunakan dalam berbagai situasi, tidak hanya dengan skrip Python.

Di sini, ia memerintahkan shell untuk memulai versi Python tertentu (untuk menjaga sisa file.


Shebang adalah konsep Unix. Mungkin perlu disebutkan bahwa ini juga berfungsi pada Windows jika Anda telah menginstal peluncur Python py.exe . Ini adalah bagian dari instalasi Python standar.
florisla

38

Alasan utama untuk melakukan ini adalah untuk membuat skrip portable di seluruh lingkungan sistem operasi.

Misalnya di bawah mingw, skrip python gunakan:

#!/c/python3k/python 

dan di bawah distribusi GNU / Linux itu adalah:

#!/usr/local/bin/python 

atau

#!/usr/bin/python

dan di bawah sistem Unix sw / hw komersial terbaik semua (OS / X), itu adalah:

#!/Applications/MacPython 2.5/python

atau di FreeBSD:

#!/usr/local/bin/python

Namun semua perbedaan ini dapat membuat skrip portable di semua dengan menggunakan:

#!/usr/bin/env python

2
Di bawah MacOSX, itu juga /usr/bin/python. Di Linux, Python yang diinstal oleh sistem juga hampir pasti /usr/bin/python(saya belum pernah melihat yang lain dan itu tidak masuk akal). Perhatikan bahwa mungkin ada sistem yang tidak memiliki /usr/bin/env.
Albert

1
Jika Anda menggunakan OSX dan menggunakan Homebrew dan mengikuti petunjuk instalasi default mereka, itu akan berada di bawah #! / Usr / local / bin / python
Will

@ Jean-PaulCalderone: Lihat jawaban saaj di bawah ini.
pydsigner

Pembaruan untuk tahun 2018: Bare pythontidak terlalu portabel, itu adalah penerjemah default Python. Arch Linux default ke Python 3 untuk waktu yang lama dan mungkin distribusi memikirkannya juga karena Python 2 hanya didukung hingga 2020.
mati865

22

Mungkin masuk akal untuk menekankan satu hal yang paling banyak terlewatkan, yang dapat mencegah pemahaman langsung. Saat Anda mengetikkan pythonterminal, biasanya Anda tidak menyediakan jalur lengkap. Sebagai gantinya, executable terlihat dalam PATHvariabel lingkungan. Pada gilirannya, ketika Anda ingin menjalankan program Python secara langsung,, /path/to/app.pyseseorang harus memberi tahu shell apa yang harus digunakan juru bahasa (melalui hashbang , apa yang dijelaskan oleh kontributor lain di atas).

Hashbang mengharapkan jalan penuh ke penerjemah. Jadi untuk menjalankan program Python Anda secara langsung, Anda harus memberikan path lengkap ke Python binary yang sangat bervariasi, terutama mengingat penggunaan virtualenv . Untuk mengatasi portabilitas, trik /usr/bin/envyang digunakan. Yang terakhir ini awalnya dimaksudkan untuk mengubah lingkungan di tempat dan menjalankan perintah di dalamnya. Ketika tidak ada perubahan disediakan itu menjalankan perintah di lingkungan saat ini, yang secara efektif menghasilkan PATHpencarian yang sama yang melakukan trik.

Sumber dari unix stackexchange


14

Ini adalah konvensi shell yang memberi tahu shell program mana yang dapat menjalankan skrip.

#! / usr / bin / env python

menyelesaikan ke jalur ke biner Python.



9

Anda dapat mencoba masalah ini menggunakan virtualenv

Inilah test.py

#! /usr/bin/env python
import sys
print(sys.version)

Buat lingkungan virtual

virtualenv test2.6 -p /usr/bin/python2.6
virtualenv test2.7 -p /usr/bin/python2.7

aktifkan masing-masing lingkungan lalu periksa perbedaannya

echo $PATH
./test.py

9

Itu hanya menentukan penerjemah apa yang ingin Anda gunakan. Untuk memahami hal ini, buat file melalui terminal dengan melakukan touch test.py, lalu ketikkan ke file itu sebagai berikut:

#!/usr/bin/env python3
print "test"

dan lakukan chmod +x test.pyuntuk membuat skrip Anda dapat dieksekusi. Setelah ini ketika Anda melakukannya, ./test.pyAnda akan mendapatkan pesan kesalahan:

  File "./test.py", line 2
    print "test"
               ^
SyntaxError: Missing parentheses in call to 'print'

karena python3 tidak mendukung operator cetak.

Sekarang, lanjutkan dan ubah baris pertama kode Anda ke:

#!/usr/bin/env python2

dan itu akan berhasil, mencetak testke stdout, karena python2 mendukung operator cetak. Jadi, sekarang Anda telah belajar cara beralih antar penerjemah skrip.


9

Sepertinya saya suka menjalankan file yang sama tanpa garis itu.

Jika demikian, maka mungkin Anda menjalankan program Python di Windows? Windows tidak menggunakan baris itu — sebaliknya, ia menggunakan ekstensi nama file untuk menjalankan program yang terkait dengan ekstensi file.

Namun pada tahun 2011, "peluncur Python" dikembangkan yang (sampai taraf tertentu) meniru perilaku Linux ini untuk Windows. Ini terbatas hanya untuk memilih interpreter Python mana yang dijalankan - misalnya untuk memilih antara Python 2 dan Python 3 pada sistem di mana keduanya diinstal. Peluncur secara opsional diinstal sebagai py.exeoleh instalasi Python, dan dapat dikaitkan dengan .pyfile sehingga peluncur akan memeriksa baris itu dan pada gilirannya meluncurkan versi interpreter Python yang ditentukan.


6
Dia mungkin juga menggunakan $ python myscript.py.
Sinan Ünür

Saya membuat kesalahan dengan tidak memiliki baris dan menggunakan python script.py, dan suatu hari saya baru saja melakukannya.
Guagua

8

Ini dimaksudkan sebagai lebih banyak informasi historis daripada jawaban "nyata".

Ingatlah bahwa di masa lalu Anda memiliki BANYAK sistem operasi unix like yang perancangnya semua memiliki gagasan sendiri tentang di mana harus meletakkan barang, dan kadang-kadang tidak termasuk Python, Perl, Bash, atau banyak hal GNU / Open Source lainnya sama sekali .

Ini bahkan berlaku untuk distribusi Linux yang berbeda. Di Linux - pra-FHS [1] -Anda mungkin memiliki python di / usr / bin / atau / usr / local / bin /. Atau mungkin belum diinstal, jadi Anda membuat sendiri dan memasukkannya ke ~ / bin

Solaris adalah yang terburuk yang pernah saya kerjakan, sebagian sebagai transisi dari Berkeley Unix ke Sistem V. Anda bisa berakhir dengan hal-hal di / usr /, / usr / local /, / usr / ucb, / opt / dll. Ini bisa membuat untuk beberapa benar-benar jalur yang panjang. Saya memiliki kenangan tentang hal-hal dari Sunfreeware.com menginstal setiap paket di direktori itu sendiri, tetapi saya tidak dapat mengingat apakah itu menyinkronkan binari ke / usr / bin atau tidak.

Oh, dan terkadang / usr / bin berada di server NFS [2].

Jadi envutilitas dikembangkan untuk mengatasi ini.

Kemudian Anda bisa menulis #!/bin/env interpreterdan selama jalannya benar, hal-hal yang wajar memiliki peluang untuk berjalan. Tentu saja, masuk akal berarti (untuk Python dan Perl) bahwa Anda juga telah menetapkan variabel lingkungan yang sesuai. Untuk bash / ksh / zsh itu hanya berfungsi.

Ini penting karena orang-orang sedang membagikan skrip shell (seperti perl dan python) dan jika Anda ingin mengode / usr / bin / python di workstation Red Hat Linux Anda, itu akan sangat buruk pada SGI ... well, tidak , Saya pikir IRIX meletakkan python di tempat yang tepat. Tetapi pada stasiun Sparc mungkin tidak berjalan sama sekali.

Saya merindukan stasiun sparc saya. Tapi tidak banyak. Ok, sekarang Anda membuat saya berkeliling di E-Bay. Bajingan.

[1] Standar Hirarki sistem file. https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard

[2] Ya, dan terkadang orang masih melakukan hal-hal seperti itu. Dan tidak, saya tidak memakai lobak ATAU bawang di ikat pinggang saya.


5

Jika Anda menjalankan skrip Anda di lingkungan virtual, katakanlah venv, mengeksekusi which pythonsambil bekerja venvakan menampilkan jalur ke juru bahasa Python:

~/Envs/venv/bin/python

Perhatikan bahwa nama lingkungan virtual tertanam di jalur ke penerjemah Python. Oleh karena itu, meng-hardcoding jalur ini dalam skrip Anda akan menyebabkan dua masalah:

  • Jika Anda mengunggah skrip ke repositori, Anda memaksa pengguna lain untuk memiliki nama lingkungan virtual yang sama . Ini jika mereka mengidentifikasi masalahnya terlebih dahulu.
  • Anda tidak akan dapat menjalankan skrip di beberapa lingkungan virtual bahkan jika Anda memiliki semua paket yang diperlukan di lingkungan virtual lainnya.

Oleh karena itu, untuk menambah jawaban Jonathan , shebang yang ideal adalah #!/usr/bin/env python, tidak hanya untuk portabilitas di seluruh OS tetapi untuk portabilitas di lingkungan virtual juga!


3

Mempertimbangkan masalah portabilitas di antara python2dan python3, Anda harus selalu menentukan versi mana pun kecuali jika program Anda kompatibel dengan keduanya.

Beberapa distribusi pengiriman pythonterhubung python3untuk sementara waktu sekarang - jangan bergantung pada pythonkeberadaan python2.

Ini ditekankan oleh PEP 394 :

Untuk mentolerir perbedaan antar platform, semua kode baru yang perlu memanggil juru bahasa Python tidak boleh menentukan python, tetapi lebih baik menentukan python2 atau python3 (atau versi python2.x dan python3.x yang lebih spesifik; lihat Migration Notes ) . Perbedaan ini harus dibuat di shebangs, ketika memohon dari skrip shell, ketika memohon melalui system () panggilan, atau ketika memohon dalam konteks lain.


2

Ini memberi tahu penerjemah versi python mana untuk menjalankan program ketika Anda memiliki banyak versi python.


0

Ini memungkinkan Anda untuk memilih executable yang ingin Anda gunakan; yang sangat berguna jika mungkin Anda memiliki beberapa pemasangan python, dan modul yang berbeda di masing-masing dan ingin memilih. misalnya

#!/bin/sh
#
# Choose the python we need. Explanation:
# a) '''\' translates to \ in shell, and starts a python multi-line string
# b) "" strings are treated as string concat by python, shell ignores them
# c) "true" command ignores its arguments
# c) exit before the ending ''' so the shell reads no further
# d) reset set docstrings to ignore the multiline comment code
#
"true" '''\'
PREFERRED_PYTHON=/Library/Frameworks/Python.framework/Versions/2.7/bin/python
ALTERNATIVE_PYTHON=/Library/Frameworks/Python.framework/Versions/3.6/bin/python3
FALLBACK_PYTHON=python3

if [ -x $PREFERRED_PYTHON ]; then
    echo Using preferred python $ALTERNATIVE_PYTHON
    exec $PREFERRED_PYTHON "$0" "$@"
elif [ -x $ALTERNATIVE_PYTHON ]; then
    echo Using alternative python $ALTERNATIVE_PYTHON
    exec $ALTERNATIVE_PYTHON "$0" "$@"
else
    echo Using fallback python $FALLBACK_PYTHON
    exec python3 "$0" "$@"
fi
exit 127
'''

__doc__ = """What this file does"""
print(__doc__)
import platform
print(platform.python_version())

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.