Skip to content

第一个 Python 程序 ​

"Hello, World!" 是几乎所有编程语言的第一课。本节将带你从零写出第一个 Python 程序,理解 print() 函数、源码文件的组织方式、注释与编码规范,并弄清交互式模式与脚本模式的区别。完成后,你就拥有了独立运行 Python 代码的完整能力。

前置知识

阅读本节前,建议先了解:Python 是什么 与 CPython 解释器原理,理解代码从源码到执行的流程。

基础概念 ​

Python 程序的最基本动作是「输出」。输出通过内置函数 print() 完成,它把参数转换成字符串并写入标准输出(Standard Output,通常是终端)。一个 Python 源文件就是一个以 .py 结尾的纯文本文件,解释器自上而下逐行执行,没有 main 函数等样板代码。

术语英文说明
源码文件Source File以 .py 结尾的文本文件
内置函数Built-in Function无需导入即可使用的函数,如 print、len
标准输出Standard Output (stdout)程序正常输出的目标
注释Comment以 # 开头,解释器忽略
编码声明Encoding Declaration声明源文件的字符编码
交互式模式Interactive Mode逐行输入并立即执行

语法与用法 ​

最简的 Python 程序只有一行:

python
# 最简可运行示例:输出一行文本
print("Hello, World!")
text
Hello, World!

把这一行保存为 hello.py,然后在终端运行:

bash
# 查看当前 Python 版本,确认环境可用
python3 --version

# 运行脚本文件
python3 hello.py
text
Python 3.12.5
Hello, World!

详细说明 ​

print() 看似简单,实际参数很丰富。它的签名可概括为 print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False):

参数类型默认值说明
*objects任意—要输出的对象,可传多个,用逗号分隔
sepstr | None' '(空格)多个对象之间的分隔符
endstr | None'\n'(换行)输出结束后的字符
file文件对象sys.stdout输出目标,可重定向到文件
flushboolFalse是否立即刷新缓冲区
python
# 多个参数会被空格连接
print("Python", "是一门", "编程语言")

# 自定义分隔符
print("2026", "10", "08", sep="-")

# 自定义结束符:不换行,同一行继续输出
print("加载中", end="")
print("...", end="")
print("完成")

# 输出空行
print()
text
Python 是一门 编程语言
2026-10-08
加载中...完成

参数之间还可以使用 * 解包序列,这在批量输出时很方便:

python
# 用 * 解包列表作为多个参数
columns = ["姓名", "年龄", "城市"]
print(*columns, sep=" | ")

# 解包 range 生成序列
print(*range(1, 6), sep=", ")
text
姓名 | 年龄 | 城市
1, 2, 3, 4, 5

注释与文档字符串 ​

Python 支持三种注释形式,用途各不相同:

python
# 单行注释:以 # 开头,一直作用到行尾
print("这行代码有效")  # 行尾注释同样以 # 开头

"""
多行字符串(Docstring):
放在模块、类或函数的第一行时,会被解释器识别为文档字符串,
可通过 __doc__ 属性或 help() 查看。它不是真正意义上的注释,
只是一段未被赋值的字符串表达式。
"""

def greet(name: str) -> str:
    """返回一句问候语(这是函数的文档字符串)"""
    return f"你好,{name}!"

print(greet("Python"))
print(greet.__doc__)  # 读取文档字符串
text
这行代码有效
你好,Python!
返回一句问候语(这是函数的文档字符串)

字符串不是注释

裸写的多行字符串只是「未被使用的表达式」,Python 不会报错,但它仍会被编译进代码对象。真正的注释应使用 #。文档字符串有明确用途(生成文档、help() 输出),不应与注释混用。

交互式模式与脚本模式的差异 ​

两种模式的执行行为不同,这是初学者最容易困惑的坑:

bash
# 进入交互式 REPL(Read-Eval-Print Loop)
python3
text
>>> 1 + 2          # 表达式会被自动打印
3
>>> print("hi")    # print 的返回值是 None,不显示
hi
>>> exit()         # 退出

在脚本文件中,只有 print() 才有输出:

python
# 脚本模式:表达式结果不会被自动打印
1 + 2                # 无任何输出(结果被丢弃)
print(1 + 2)         # 显式打印,输出 3
text
3
对比项交互式模式脚本模式
触发方式直接输入 python3python3 file.py
表达式结果自动打印不打印
提示符>>> 与 ...无
适用场景试验语法、调试片段编写可复用程序
多行代码需用空行结尾直接书写缩进块

编码、缩进与文件编码声明 ​

Python 3 源码默认使用 UTF-8 编码,因此可以直接书写中文,无需声明:

python
# Python 3 默认 UTF-8,中文可直接使用
message: str = "你好,世界!"
print(message)

# 若因历史原因使用非 UTF-8 编码,需在文件首行声明(仅 Python 2 必需)
# -*- coding: utf-8 -*-
text
你好,世界!

缩进是 Python 的语法,而非风格建议。同一代码块必须使用一致的缩进(推荐 4 个空格):

python
# 正确:4 空格缩进
def check(value: int) -> str:
    if value > 0:
        return "正数"
    return "非正数"

print(check(5))
print(check(-1))
text
正数
非正数
python
# 错误!混用 Tab 与空格会触发 TabError
def broken(value: int) -> str:
	if value > 0:      # 这里用了 Tab
        return "正数"   # 这里用了空格
    return "非零"

输入与输出的结合 ​

input() 函数从标准输入读取一行文本,返回值总是 str 类型:

python
# 读取用户输入并处理
name = input("请输入你的名字:")   # 例如输入:小码农
print(f"你好,{name}!欢迎学习 Python。")

# 注意:input() 返回字符串,做算术需显式转换
age_text = input("请输入你的年龄:")   # 例如输入:28
age = int(age_text)
print(f"明年你 {age + 1} 岁")
text
请输入你的名字:小码农
你好,小码农!欢迎学习 Python。
请输入你的年龄:28
明年你 29 岁

不要忘记类型转换

input() 永远返回字符串。直接对输入做算术会触发 TypeError。必须先用 int()、float() 转换。

python
# 错误!字符串与整数不能相加
age = input("年龄:")   # 返回 "28"
# print(age + 1)       # TypeError: can only concatenate str (not "int") to str

# 正确:先转换类型
age = int(input("年龄:"))
print(age + 1)
text
年龄:28
29

程序入口与 __name__ ​

标准库与其他模块导入你的文件时,__name__ 的值是模块名;直接运行时是 "__main__"。这是控制「仅直接运行才执行」的关键:

python
# 演示:查看 __name__ 的值
print(f"当前 __name__ = {__name__}")

def main() -> None:
    """程序主逻辑"""
    print("主逻辑执行中")

# 仅当本文件被直接运行时才执行 main()
if __name__ == "__main__":
    main()
text
当前 __name__ = __main__
主逻辑执行中

如果这个文件被其他文件 import,则 __name__ 会是模块名,main() 不会执行——这正是脚本既能独立运行、又能被复用的原因。

实战示例 ​

示例一:个人信息卡片生成器 ​

把输入、类型转换、格式化输出组合成一个完整小工具:

python
def build_card(name: str, age: int, city: str, job: str) -> str:
    """根据个人信息生成一张文本卡片"""
    border = "=" * 30
    lines = [
        border,
        f"{'个人信息卡片':^24}",   # ^ 表示居中对齐
        border,
        f"姓 名:{name}",
        f"年 龄:{age} 岁",
        f"城 市:{city}",
        f"职 业:{job}",
        border,
    ]
    return "\n".join(lines)

def main() -> None:
    """采集信息并输出卡片"""
    name = input("姓名:")
    age = int(input("年龄:"))
    city = input("城市:")
    job = input("职业:")
    print()
    print(build_card(name, age, city, job))

if __name__ == "__main__":
    main()
text
姓名:小码农
年龄:28
城市:杭州
职业:后端工程师

==============================
          个人信息卡片
==============================
姓 名:小码农
年 龄:28 岁
城 市:杭州
职 业:后端工程师
==============================

示例二:命令行问候工具 ​

下面这个脚本读取命令行参数,输出定制问候,并演示如何输出到文件:

python
import sys
from datetime import datetime
from pathlib import Path

def greet(names: list[str]) -> str:
    """生成对所有名字的问候语"""
    now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    lines = [f"[{now}] 你好,{name}!" for name in names]
    return "\n".join(lines)

def main() -> None:
    """读取命令行参数,输出问候并写入日志文件"""
    # sys.argv[0] 是脚本名,之后的才是用户参数
    names = sys.argv[1:] or ["世界"]
    result = greet(names)

    print(result)

    # 同时写入日志文件,便于留痕
    log_file = Path("greeting.log")
    with log_file.open("a", encoding="utf-8") as file:
        file.write(result + "\n")
    print(f"(已追加写入 {log_file})")

if __name__ == "__main__":
    main()
bash
# 运行示例
python3 greet.py Python PHP Go
text
[2026-10-08 10:30:00] 你好,Python!
[2026-10-08 10:30:00] 你好,PHP!
[2026-10-08 10:30:00] 你好,Go!
(已追加写入 greeting.log)

示例三:常见输出格式速查 ​

print() 结合 f-string 可完成各类格式化输出:

需求写法输出
右对齐数字f"{42:>8}" 42
左对齐文本`f"{'abc':<8}"`
居中f"{'标题':^10}" 标题
保留两位小数f"{3.14159:.2f}"3.14
千分位f"{1234567:,}"1,234,567
百分比f"{0.856:.1%}"85.6%
补零f"{7:03d}"007
python
# 格式化输出综合演示
price = 1299.5
discount = 0.85
count = 7

print(f"原价:{price:>12,.2f} 元")
print(f"折扣:{discount:>12.1%}")
print(f"折后:{price * discount:>12,.2f} 元")
print(f"编号:{count:03d}")
text
原价:    1,299.50 元
折扣:       85.0%
折后:    1,104.58 元
编号:007

注意事项 ​

  • input() 返回字符串:做数学运算前必须用 int() 或 float() 转换,否则触发 TypeError。
  • 缩进必须一致:同一代码块内不能混用 Tab 和空格,推荐统一使用 4 个空格。
  • 脚本模式不会自动打印表达式:只有 print() 才有输出。
  • 字符串不是注释:裸写的多行字符串会被编译进代码,只有 # 才是真正的注释。
  • 文件名不要用中文或特殊字符:尽量用小写英文加下划线,避免跨平台问题。
  • python 与 python3 可能不同:macOS/Linux 上建议始终使用 python3。
  • 避免文件名为 os.py 等标准库名:会遮蔽标准库模块,导致诡异错误。

最佳实践 ​

  • 代码块顶部写模块文档字符串:说明脚本用途,便于他人与工具理解。
  • 使用 if __name__ == "__main__": 包裹主逻辑:让文件可导入、可测试。
  • 优先使用 f-string:Python 3.6+ 的 f-string 可读性与性能都优于 % 和 str.format()。
  • 用 pathlib 处理路径:不要手写 / 或 \ 拼接,避免跨平台问题。
  • 把常量提取为具名变量:如 BORDER = "=" * 30,避免魔法值散落。
  • 写清晰的函数名与类型提示:即使简单脚本,也养成标注参数类型的习惯。
python
# 推荐:结构清晰的脚本模板
#!/usr/bin/env python3
"""脚本模板:展示推荐的代码组织方式"""
import sys

BORDER: str = "=" * 40

def main(argv: list[str]) -> int:
    """程序入口,返回退出码"""
    print(BORDER)
    print(f"参数数量:{len(argv)}")
    print(BORDER)
    return 0

if __name__ == "__main__":
    # 用 SystemExit 把退出码传给操作系统
    raise SystemExit(main(sys.argv[1:]))
text
========================================
参数数量:0
========================================

下一节

继续学习:使用 Python 作为计算器

参考链接 ​