Upgrade to Pro — share decks privately, control downloads, hide ads and more …

print("Hello, World")

Avatar for 高見龍 高見龍
September 06, 2025

print("Hello, World")

Avatar for 高見龍

高見龍

September 06, 2025

More Decks by 高見龍

Other Decks in Programming

Transcript

  1. PyCon Taiwan 自我介紹 高見龍 @ 五倍學院 ๏ 程式開發 ≒ 30

    年 ๏ 教學經驗 ≒ 16 年 ๏ 出版 : ๏「為你自己學 Git」 ๏「為你自己學 Ruby on Rails」 ๏「為你自己學 Python」 ๏ 是個喜歡打魔物獵人而且希望可以寫一 輩子程式的電腦阿宅
  2. PyCon Taiwan a = 1 + 2 NAME (a) EQUAL

    (=) NUMBER (1) PLUS (+) NUMBER (2)
  3. PyCon Taiwan int _PyTokenizer_Get(struct tok_state *tok, struct token *token) {

    int result = tok_get(tok, token); if (tok->decoding_erred) { result = ERRORTOKEN; tok->done = E_DECODE; } return result; } 檔名:Parser/tokenizer.c
  4. PyCon Taiwan ENDMARKER NAME NUMBER STRING NEWLINE INDENT DEDENT LPAR

    '(' RPAR ')' LSQB '[' RSQB ']' COLON ':' COMMA ',' SEMI ';' PLUS '+' MINUS '-' // ... 略 檔名:Grammar/Tokens
  5. PyCon Taiwan 0 0 RESUME 0 1 2 LOAD_CONST 0

    (<code object greeting at 0x102b1f5d0, file "hello.py", line 1>) 4 MAKE_FUNCTION 0 6 STORE_NAME 0 (greeting) 4 8 PUSH_NULL 10 LOAD_NAME 1 (print) 12 PUSH_NULL 14 LOAD_NAME 0 (greeting) 16 LOAD_CONST 1 ('Kitty') 18 CALL 1 26 CALL 1 34 POP_TOP 36 RETURN_CONST 2 (None) Disassembly of <code object greeting at 0x102b1f5d0, file "hello.py", line 1>: 1 0 RESUME 0 2 2 LOAD_CONST 1 ('Hello, ') 4 LOAD_FAST 0 (name) 6 FORMAT_VALUE 0 8 LOAD_CONST 2 ('!') 10 BUILD_STRING 3 12 RETURN_VALUE 行號
  6. PyCon Taiwan ٩(ˊᗜˋ*)و🍟🧋❯ lldb ./python.exe hello.py (lldb) target create "./python.exe"

    Current executable set to '/Users/kaochenlong/projects/ sources/python/cpython/python.exe' (arm64). (lldb) settings set -- target.run-args "hello.py" (lldb) breakpoint set --name main Breakpoint 1: 13 locations. (lldb) 中斷點
  7. PyCon Taiwan ٩(ˊᗜˋ*)و🍟🧋❯ (lldb) run Process 80499 launched: '/Users/kaochenlong/projects/sources/python/ cpython/python.exe'

    (arm64) Process 80499 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0: 0x0000000100003d1c python.exe`main(argc=2, argv=0x000000016fdfe758) at python.c:15:12 [opt] 12 int 13 main(int argc, char **argv) 14 { -> 15 return Py_BytesMain(argc, argv); 16 } 17 #endif Target 0: (python.exe) stopped. warning: python.exe was compiled with optimization - stepping may behave oddly; variables may not be available. (lldb) 進入點
  8. PyCon Taiwan int Py_BytesMain(int argc, char **argv) { _PyArgv args

    = { .argc = argc, .use_bytes_argv = 1, .bytes_argv = argv, .wchar_argv = NULL}; return pymain_main(&args); } 檔名:Modules/main.c
  9. PyCon Taiwan static int pymain_main(_PyArgv *args) { PyStatus status =

    pymain_init(args); if (_PyStatus_IS_EXIT(status)) { pymain_free(); return status.exitcode; } if (_PyStatus_EXCEPTION(status)) { pymain_exit_error(status); } return Py_RunMain(); } 檔名:Modules/main.c
  10. PyCon Taiwan int Py_RunMain(void) { int exitcode = 0; pymain_run_python(&exitcode);

    if (Py_FinalizeEx() < 0) { /* Value unlikely to be confused with a non-error exit status or other special meaning */ exitcode = 120; } pymain_free(); if (_PyRuntime.signals.unhandled_keyboard_interrupt) { exitcode = exit_sigint(); } return exitcode; } 檔名:Modules/main.c
  11. PyCon Taiwan static void pymain_run_python(int *exitcode) { // ... 略

    ... if (config->run_command) { *exitcode = pymain_run_command(config->run_command); } else if (config->run_module) { *exitcode = pymain_run_module(config->run_module, 1); } else if (main_importer_path != NULL) { *exitcode = pymain_run_module(L"__main__", 0); } else if (config->run_filename != NULL) { *exitcode = pymain_run_file(config); } else{ *exitcode = pymain_run_stdin(config); } // ... 略 ... } python -c "print('hello')" python -m module_name python hello.py 檔名:Modules/main.c
  12. PyCon Taiwan static int pymain_run_file(const PyConfig *config) { // ...

    略 ... int res = pymain_run_file_obj(program_name, filename, config->skip_source_first_line); Py_DECREF(filename); Py_DECREF(program_name); return res; } 檔名:Modules/main.c
  13. PyCon Taiwan static int pymain_run_file_obj(PyObject *program_name, PyObject *filename, int skip_source_first_line)

    { // ... 略 ... FILE *fp = _Py_fopen_obj(filename, "rb"); // ... 略 ... PyCompilerFlags cf = _PyCompilerFlags_INIT; int run = _PyRun_AnyFileObject(fp, filename, 1, &cf); return (run != 0); } 檔名:Modules/main.c
  14. PyCon Taiwan int _PyRun_AnyFileObject(FILE *fp, PyObject *filename, int closeit, PyCompilerFlags

    *flags) { // ... 略 ... int res; if (_Py_FdIsInteractive(fp, filename)) { res = _PyRun_InteractiveLoopObject(fp, filename, flags); if (closeit) { fclose(fp); } } else { res = _PyRun_SimpleFileObject(fp, filename, closeit, flags); } // ... 略 ... } 檔名:Modules/main.c
  15. PyCon Taiwan int _PyRun_SimpleFileObject(FILE *fp, PyObject *filename, int closeit, PyCompilerFlags

    *flags) { // ... 略 ... m = PyImport_AddModule("__main__"); // ... 略 ... int pyc = maybe_pyc_file(fp, filename, closeit); // ... 略 ... if (pyc) { FILE *pyc_fp; // ... 略 ... v = run_pyc_file(pyc_fp, d, d, flags); } else { // ... 略 ... v = pyrun_file(fp, filename, Py_file_input, d, d, closeit, flags); } // ... 略 ... } __main__ 檔名:Python/pythonrun.c ?
  16. PyCon Taiwan static PyObject * pyrun_file(FILE *fp, PyObject *filename, int

    start, PyObject *globals, PyObject *locals, int closeit, PyCompilerFlags *flags) { // ... 略 ... PyArena *arena = _PyArena_New(); // ... 略 ... mod_ty mod; mod = _PyParser_ASTFromFile(fp, filename, NULL, start, NULL, NULL, flags, NULL, arena); // ... 略 ... } 檔名:Python/pythonrun.c
  17. PyCon Taiwan static PyObject * run_mod(mod_ty mod, PyObject *filename, PyObject

    *globals, PyObject *locals, PyCompilerFlags *flags, PyArena *arena) { PyThreadState *tstate = _PyThreadState_GET(); PyCodeObject *co = _PyAST_Compile(mod, filename, flags, -1, arena); // ... 略 ... PyObject *v = run_eval_code_obj(tstate, co, globals, locals); Py_DECREF(co); return v; } 檔名:Python/pythonrun.c
  18. PyCon Taiwan static PyObject * run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject

    *globals, PyObject *locals) { PyObject *v; _PyRuntime.signals.unhandled_keyboard_interrupt = 0; // ... 略 ... v = PyEval_EvalCode((PyObject*)co, globals, locals); if (!v && _PyErr_Occurred(tstate) == PyExc_KeyboardInterrupt) { _PyRuntime.signals.unhandled_keyboard_interrupt = 1; } return v; } 檔名:Python/pythonrun.c
  19. PyCon Taiwan int _PyRun_SimpleFileObject(FILE *fp, PyObject *filename, int closeit, PyCompilerFlags

    *flags) { // ... 略 ... m = PyImport_AddModule("__main__"); // ... 略 ... int pyc = maybe_pyc_file(fp, filename, closeit); // ... 略 ... if (pyc) { FILE *pyc_fp; // ... 略 ... v = run_pyc_file(pyc_fp, d, d, flags); } else { // ... 略 ... v = pyrun_file(fp, filename, Py_file_input, d, d, closeit, flags); } // ... 略 ... } 檔名:Python/pythonrun.c ?
  20. PyCon Taiwan static int maybe_pyc_file(FILE *fp, PyObject *filename, int closeit)

    { PyObject *ext = PyUnicode_FromString(".pyc"); if (ext == NULL) { return -1; } // ... 略 ... /* Read only two bytes of the magic. If the file was opened in text mode, the bytes 3 and 4 of the magic (\r\n) might not be read as they are on disk. */ unsigned int halfmagic = PyImport_GetMagicNumber() & 0xFFFF; unsigned char buf[2]; // ... 略 ... } 檔名:Python/pythonrun.c
  21. PyCon Taiwan long PyImport_GetMagicNumber(void) { long res; PyInterpreterState *interp =

    _PyInterpreterState_GET(); PyObject *external, *pyc_magic; external = PyObject_GetAttrString(IMPORTLIB(interp), "_bootstrap_external"); if (external == NULL) return -1; pyc_magic = PyObject_GetAttrString(external, "_RAW_MAGIC_NUMBER"); Py_DECREF(external); if (pyc_magic == NULL) return -1; res = PyLong_AsLong(pyc_magic); Py_DECREF(pyc_magic); return res; } 檔名:Python/import.c
  22. PyCon Taiwan MAGIC_NUMBER = (3531).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER =

    int.from_bytes(MAGIC_NUMBER, 'little') 檔名:Lib/importlib/_bootstrap_external.py
  23. PyCon Taiwan # Known values: # Python 1.5: 20121 #

    Python 1.5.1: 20121 # Python 1.5.2: 20121 # Python 1.6: 50428 # Python 2.0: 50823 # ... 略 ... # Python 2.7a0 62211 (introduce MAP_ADD and SET_ADD) # Python 3000: 3000 # 3010 (removed UNARY_CONVERT) # ... 略 ... # Python 3.12b1 3530 (Shrink the LOAD_SUPER_ATTR caches) # Python 3.12b1 3531 (Add PEP 695 changes) # Python 3.13 will start with 3550 檔名:Lib/importlib/_bootstrap_external.py
  24. PyCon Taiwan # Python 3.11.9 >>> from importlib._bootstrap_external import MAGIC_NUMBER

    >>> MAGIC_NUMBER b'\xa7\r\r\n' # Python 3.12.6 >>> from importlib._bootstrap_external import MAGIC_NUMBER >>> MAGIC_NUMBER b'\xcb\r\r\n'
  25. PyCon Taiwan /* Mess: In case of -x, the stream

    is NOT at its start now, and ungetc() was used to push back the first newline, which makes the current stream position formally undefined, and a x-platform nightmare. Unfortunately, we have no direct way to know whether -x was specified. So we use a terrible hack: if the current stream position is not 0, we assume -x was specified, and give up. Bug 132850 on SourceForge spells out the hopelessness of trying anything else (fseek and ftell don't work predictably x-platform for text-mode files). */ 檔名:Python/pythonrun.c
  26. PyCon Taiwan ٩(ˊᗜˋ*)و🍟🧋❯ ./python.exe pyc_demo.py b'\xcb\r\r\n\x00\x00\x00\x00\xce\xac\xbchK\x00\x00\x00\xe3\x00\x00\x00\x00\x 00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\xf3&\x00\x00\ x00\x97\x00d\x00\x84\x00Z\x00\x02\x00e\x01\x02\x00e\x00d\x01\xab\x01\x00\x00 \x00\x00\x00\x00\xab\x01\x00\x00\x00\x00\x00\x00\x01\x00y\x02)\x03c\x01\x00\ x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\xf3\

    x0e\x00\x00\x00\x97\x00d\x01|\x00\x9b\x00d\x02\x9d\x03S\x00)\x03Nz\x07Hello, \xfa\x01!\xa9\x00)\x01\xda\x04names\x01\x00\x00\x00 \xfa\x08hello.py\xda\x08greetingr\x07\x00\x00\x00\x01\x00\x00\x00s\x11\x00\x 00\x00\x80\x00\xd8\r\x14\x90T\x90F\x98! \xd0\x0b\x1c\xd0\x04\x1c\xf3\x00\x00\x00\x00\xda\x05KittyN) \x02r\x07\x00\x00\x00\xda\x05printr\x04\x00\x00\x00r\x08\x00\x00\x00r\x06\x0 0\x00\x00\xfa\x08<module>r\x0b\x00\x00\x00\x01\x00\x00\x00s\x19\x00\x00\x00\ xf0\x03\x01\x01\x01\xf2\x02\x01\x01\x1d\xf1\x06\x00\x01\x06\x81h\x88w\xd3\x0 6\x17\xd5\x00\x18r\x08\x00\x00\x00'
  27. PyCon Taiwan import marshal with open("__pycache__/hello.cpython-312.pyc", "rb") as f: f.read(16)

    content = marshal.load(f) code_object = content.co_code print(type(content)) print(code_object) print(list(code_object)) 魔術 數字 檔名:pyc_demo2.py
  28. PyCon Taiwan #define CACHE 0 #define POP_TOP 1 #define PUSH_NULL

    2 #define INTERPRETER_EXIT 3 #define END_FOR 4 // ... 略 ... #define LOAD_CONST 100 #define LOAD_NAME 101 #define BUILD_TUPLE 102 #define BUILD_LIST 103 // ... 略 ... #define COPY_FREE_VARS 149 #define YIELD_VALUE 150 #define RESUME 151 // ... 略 ... 檔名:Include/opcode.h
  29. PyCon Taiwan >>> import dis >>> ops = [151, 0,

    100, 0, 132, 0, 90, 0, 2, 0, 101, 1, 2, 0, 101, 0, 100, 1, 171, 1, 0, 0, 0, 0, 0, 0, 171, 1, 0, 0, 0, 0, 0, 0, 1, 0, 121, 2] >>> for op in ops: ... print(dis.opname[op]) ... RESUME CACHE LOAD_CONST CACHE MAKE_FUNCTION CACHE STORE_NAMECACHE CACHE POP_TOP CACHE RETURN_CONST PUSH_NULL
  30. PyCon Taiwan 為你自己讀 CPython 原始碼 第 1 章:來讀 CPython 原始碼

    第 2 章:CPython 專案簡介 第 3 章:全部都是物件(上) 第 4 章:物件 生 成全紀錄 第 5 章:全部都是物件(下) 第 6 章:我的 Python 會後空翻! 第 7 章:匯入模組的時候... 第 8 章:整數的前世今 生 第 9 章:浮點數之 小 數點漂流記 第 10 章:字串的秘密 生 活(上) 第 11 章:字串的秘密 生 活(下) 第 12 章:從準備到起 飛 ! 第 13 章:參觀 Bytecode 工 廠 第 14 章:串列的排隊 人生 第 15 章:字典的整理收納課(上) 第 16 章:字典的整理收納課(下) 第 17 章:不動如 山 的 Tuple 第 18 章:虛擬機器五部曲( 一 ) 第 19 章:虛擬機器五部曲( 二 ) 第 20 章:虛擬機器五部曲(三) 第 21 章:虛擬機器五部曲(四) 第 22 章:虛擬機器五部曲(五) 第 23 章:類別與它們的產地 第 24 章:繼承與家族紛爭(上) 第 25 章:繼承與家族紛爭(中) 第 26 章:繼承與家族紛爭(下) 第 27 章:產 生 一 個產 生 器 第 28 章:轉呀轉呀七彩迭代器 第 29 章:無所不在的描述器 第 30 章:例外處理的幕後真相 今天的 內容