资讯中心

Python新手入门:从基础语法到核心数据结构与函数封装

📅 2026/8/13 10:38:39
Python新手入门:从基础语法到核心数据结构与函数封装
1. 项目概述为什么Python是新手入门的首选如果你正站在编程世界的门口看着琳琅满目的语言列表感到迷茫不知道该先迈出哪一步那么我以一个过来人的经验告诉你从Python开始大概率不会错。我见过太多朋友从C语言的指针和内存管理开始被劝退在半路也见过有人一头扎进Java的面向对象和复杂配置里还没写出像样的东西就失去了兴趣。而Python就像一个设计精良的“新手村”它用最直观的方式让你快速感受到“创造”的乐趣建立起最初的信心。Python的基础语法就是这座新手村的地图和操作手册。它不像一些语言那样充满了晦涩的符号和复杂的规则。它的设计哲学是“优雅、明确、简单”读起来常常像在读一段简单的英文说明。比如你想在屏幕上打印“Hello, World!”在Python里就是一行直白的print(“Hello, World!”)。这种低门槛的直观性能让你把宝贵的脑力集中在解决问题的逻辑上而不是和语法规则搏斗。更重要的是Python的“实用性”极强。你学到的每一个基础语法点几乎都能立刻找到用武之地。学完变量和数据类型你就能写个小程序算算自己的BMI指数学完列表和循环你就能批量处理文件或者分析简单的数据学完函数你就能把代码组织得井井有条。这种“学了就能用用了就见效”的正向反馈是支撑初学者走下去的最大动力。无论你未来是想做数据分析、人工智能、网站开发还是自动化脚本Python的基础语法都是那块最坚实、最通用的基石。接下来我们就抛开那些空洞的“Python很好”的论调直接上手看看这块基石到底长什么样以及如何稳稳地把它砌好。2. 核心基石变量、数据类型与基本运算任何程序本质上都是在处理数据而Python为我们提供了清晰、灵活的工具来“描述”和“操作”这些数据。理解变量和数据类型就像学做饭前先认识油盐酱醋和各种食材这是你写出任何有效代码的前提。2.1 变量数据的“便利贴”在Python里变量就是一个名字它贴在某一块数据上方便我们引用。最妙的是你不需要像在一些语言里那样事先声明“我要一个装数字的盒子”或“我要一个装文字的盒子”。Python是动态类型的你直接“贴”就行。name “张三” # 把字符串“张三”贴上了“name”这个标签 age 25 # 把整数25贴上了“age”这个标签 height 1.75 # 把浮点数1.75贴上了“height”这个标签 is_student True # 把布尔值True贴上了“is_student”这个标签这里有个非常重要的实操心得给变量起个好名字。别用a,b,c这种毫无意义的名字。尽量使用英文单词或缩写做到见名知义。比如user_name就比n好total_price就比tp好。这不仅是好习惯更能让你在几天后回看代码时不至于一头雾水。2.2 基本数据类型认识你的“食材”Python内置了几种最常用的数据类型你需要像熟悉朋友一样熟悉它们整数int和浮点数float用于数学计算。10,-5是整数3.14,2.0是浮点数。需要注意的是在Python 3中整数除法/的结果默认是浮点数如5 / 2结果是2.5如果你想得到整数商要用//如5 // 2结果是2。字符串str用单引号‘’或双引号“”包裹的文本。‘hello’和“world”都是字符串。它们支持非常灵活的操作greeting “Hello” name “Python” # 拼接 full_greeting greeting “, ” name “!” # 结果是 “Hello, Python!” # 重复 laugh “ha” * 3 # 结果是 “hahaha” # 格式化现代推荐方式 message f“{greeting}, {name}! You are {age} years old.” # f-string非常清晰布尔值bool只有True和False两个值主要用于逻辑判断。它们通常是比较运算或逻辑运算的结果。is_equal (10 10) # True is_greater (5 10) # False空值NoneType只有一个值None。它表示“什么都没有”或“空”常用于初始化变量或作为函数的默认返回值。注意新手常犯的一个错误是混淆赋值和等于比较。是把右边的值贴到左边的变量名上是检查左右两边的值是否相等返回True或False。2.3 类型查看与转换你怎么知道一个变量现在贴着什么类型的数据呢用type()函数。print(type(age)) # 输出class ‘int’ print(type(name)) # 输出class ‘str’ print(type(height)) # 输出class ‘float’有时我们需要在不同类型间转换比如把用户输入的字符串数字转换成整数进行计算。num_str “123” num_int int(num_str) # 字符串转整数得到 123 num_float float(num_str) # 字符串转浮点数得到 123.0 result_str str(100) # 整数转字符串得到 “100”这里有个坑如果num_str不是合法的数字字符串比如“abc”int()或float()转换时会抛出ValueError错误。在实际编程中对用户输入进行转换时最好用try…except进行异常处理这个我们后面会讲到。3. 程序的控制流让代码“活”起来只会定义变量和做计算写出的程序是“死”的它只会从上到下执行一遍。控制流语句条件判断和循环赋予了程序“决策”和“重复”的能力这才是编程逻辑的核心体现。3.1 条件判断if/elif/else程序的路由器根据不同的条件执行不同的代码块。语法结构非常像自然语言score 85 if score 90: grade “A” print(“优秀”) elif score 80: grade “B” print(“良好”) elif score 60: grade “C” print(“及格”) else: grade “D” print(“不及格需要努力”)关键细节与避坑指南冒号和缩进是生命线if,elif,else后面必须跟冒号:。下面隶属于该条件判断的代码块必须严格缩进通常用4个空格。Python没有用大括号{}来界定代码块缩进就是语法的一部分。缩进不一致会直接导致IndentationError。判断条件条件表达式的结果必须是布尔值True或False。你可以使用比较运算符,!,,,,和逻辑运算符and,or,not来构建复杂的条件。if age 18 and has_id_card: # 必须同时满足两个条件 print(“允许进入。”) if not is_weekend: # 如果不是周末 print(“今天是工作日。”)elif和else是可选的但if必须有。elif是“否则如果”的意思可以有多个。else是“否则”处理所有未被前面条件覆盖的情况。3.2 循环for/while自动化的引擎for循环常用于遍历一个已知的序列如列表、字符串、数字范围。# 遍历列表 fruits [“apple”, “banana”, “orange”] for fruit in fruits: print(f“I like {fruit}.”) # 遍历数字序列 range(start, stop, step) for i in range(5): # 从0到4共5次循环 print(i) # 输出 0, 1, 2, 3, 4 for i in range(1, 10, 2): # 从1开始到9结束步长为2 print(i) # 输出 1, 3, 5, 7, 9while循环只要条件为True就重复执行代码块。常用于你不知道具体要循环多少次直到某个条件被满足的场景。count 0 while count 5: print(f“Count is {count}”) count 1 # 千万别忘了改变条件变量否则会陷入死循环循环控制语句break立即终止整个循环。continue跳过当前循环的剩余语句直接进入下一次循环。for i in range(10): if i 3: continue # 当i等于3时跳过下面的print直接进入i4的循环 if i 7: break # 当i等于7时整个循环结束 print(i) # 输出0, 1, 2, 4, 5, 6重要心得警惕死循环。写while循环时必须确保循环体内的操作能在某个时刻让条件变为False。最常见的错误是忘了更新条件变量如上面的count 1。如果不小心写出了死循环在命令行中可以用Ctrl C来强制中断程序。4. 核心数据结构列表、元组、字典与集合当数据不止一个时我们需要容器来组织它们。Python提供了四种强大的内置数据结构它们各有特点适用于不同的场景。4.1 列表List你的万能收纳盒列表用方括号[]表示元素之间用逗号分隔。它是有序、可变的可以存放任意类型的数据甚至混合存放。my_list [1, 2, “hello”, 3.14, True] # 混合类型 empty_list [] # 空列表核心操作增my_list.append(“new_item”) # 在末尾添加一个元素 my_list.insert(1, “inserted”) # 在索引1的位置插入元素删last_item my_list.pop() # 删除并返回末尾元素 second_item my_list.pop(1) # 删除并返回索引1的元素 my_list.remove(“hello”) # 删除第一个值为“hello”的元素改直接通过索引赋值。my_list[0] “first” # 将索引0的元素改为“first”查通过索引从0开始或切片。print(my_list[2]) # 输出索引为2的元素 print(my_list[-1]) # 输出最后一个元素 print(my_list[1:4]) # 切片输出索引1到3的元素不包含4 print(my_list[:3]) # 从开头到索引2 print(my_list[2:]) # 从索引2到末尾注意事项列表的切片操作返回的是一个新的列表是原列表部分元素的浅拷贝。对于简单数据没问题但如果列表里嵌套了其他可变对象如另一个列表修改切片可能会影响原列表这里涉及“浅拷贝”和“深拷贝”的概念新手可以先记住这个现象在遇到复杂结构时再深入研究。4.2 元组Tuple一次定型的保险箱元组用圆括号()表示。它是有序、不可变的。一旦创建就不能修改其中的元素。my_tuple (1, 2, “apple”) # my_tuple[0] 100 # 这行会报错TypeError元组不可变既然不可变为什么要用它主要有两个优势1.安全性。确保数据不会被意外修改。2.性能。不可变对象在Python内部处理起来更快并且可以作为字典的键而列表不能。当你需要存储一组无需改变的数据时如坐标点point (x, y)元组是更好的选择。4.3 字典Dictionary高效的查找表字典用花括号{}表示存储的是键-值对Key-Value Pair。它是无序、可变的键必须是不可变类型如字符串、数字、元组值可以是任意类型。student { “name”: “李四”, “age”: 20, “courses”: [“数学”, “物理”] }核心操作增/改通过键直接赋值。student[“grade”] “A” # 新增键值对 student[“age”] 21 # 修改已有键的值删grade student.pop(“grade”) # 删除键“grade”并返回其值 del student[“age”] # 删除键“age”查print(student[“name”]) # 直接通过键访问如果键不存在会报KeyError print(student.get(“age”)) # 使用get方法键不存在时返回None可指定默认值如get(“age”, 0)遍历字典for key in student: # 遍历所有键 print(key) for value in student.values(): # 遍历所有值 print(value) for key, value in student.items(): # 同时遍历键和值最常用 print(f“{key}: {value}”)4.4 集合Set去重与集合运算集合用花括号{}或set()函数创建。它是无序、可变、元素不重复的。主要用途是去重和进行集合运算交集、并集、差集。my_set {1, 2, 2, 3, 4} # 创建时自动去重结果为 {1, 2, 3, 4} another_set set([3, 4, 5, 6]) # 从列表创建 # 集合运算 print(my_set another_set) # 交集{3, 4} print(my_set | another_set) # 并集{1, 2, 3, 4, 5, 6} print(my_set - another_set) # 差集在my_set中但不在another_set中{1, 2}选择哪种数据结构取决于你的需求需要有序、可变的序列用列表需要不可变的序列用元组需要通过键快速查找值用字典需要确保元素唯一性或做集合运算用集合。5. 函数封装与复用的艺术当你发现某段代码在程序里反复出现或者一段代码逻辑特别复杂时就该考虑把它封装成函数了。函数是组织代码、实现复用的基本单元。5.1 定义与调用从“怎么做”到“做什么”定义函数使用def关键字。def greet(name): “”“这是一个简单的问候函数”“” # 文档字符串说明函数用途 message f“Hello, {name}!” return messagedef定义函数的关键字。greet函数名应遵循变量命名规则最好用动词或动宾短语。(name)参数列表。name是形式参数形参调用时需要传入实际的值。:“冒号表示函数体开始。“”“…””“文档字符串用于说明函数功能良好的习惯。return message使用return语句返回结果。如果没有return函数默认返回None。调用函数result greet(“王五”) # “王五”是实际参数实参 print(result) # 输出Hello, 王五!5.2 参数传递的多种玩法位置参数最常见的传参方式实参与形参按位置顺序一一对应。def describe_pet(animal_type, pet_name): print(f“I have a {animal_type} named {pet_name}.”) describe_pet(“hamster”, “Harry”) # animal_type“hamster”, pet_name“Harry”关键字参数在调用时指定参数名这样就不必拘泥于顺序。describe_pet(pet_name“Harry”, animal_type“hamster”) # 顺序打乱也没问题默认参数在定义函数时给形参指定默认值。调用时如果不传就使用默认值。def describe_pet(pet_name, animal_type“dog”): # animal_type有默认值 print(f“I have a {animal_type} named {pet_name}.”) describe_pet(“Willie”) # 输出I have a dog named Willie. describe_pet(“Harry”, “hamster”) # 输出I have a hamster named Harry.注意默认参数必须放在非默认参数之后。否则会引发语法错误。可变参数有时你无法确定调用者会传入多少个参数。使用*args可以接收任意数量的位置参数并将其打包成一个元组。def make_pizza(*toppings): print(“Making a pizza with the following toppings:”) for topping in toppings: print(f“- {topping}”) make_pizza(“pepperoni”) make_pizza(“mushrooms”, “green peppers”, “extra cheese”)关键字可变参数使用**kwargs可以接收任意数量的关键字参数并将其打包成一个字典。def build_profile(first, last, **user_info): profile {‘first_name’: first, ‘last_name’: last} for key, value in user_info.items(): profile[key] value return profile user_profile build_profile(‘albert’, ‘einstein’, location‘princeton’, field‘physics’) print(user_profile)5.3 变量的作用域搞清楚谁在哪儿能被看见这是一个容易混淆的概念。简单来说局部变量在函数内部定义的变量只在函数内部有效。函数执行完毕后局部变量就被销毁了。全局变量在函数外部定义的变量在整个程序文件中都有效。x “global” # 全局变量 def my_func(): y “local” # 局部变量 print(f“Inside function: x{x}, y{y}”) # 可以访问全局x和局部y my_func() print(f“Outside function: x{x}”) # 可以访问全局x # print(y) # 这里会报错NameErrory是局部变量在外面不可见如果你想在函数内部修改全局变量需要使用global关键字声明。count 0 def increment(): global count # 声明count是全局变量 count 1 increment() print(count) # 输出1强烈建议除非有非常充分的理由否则尽量避免在函数内部修改全局变量。这会让程序的状态难以追踪是产生bug的温床。更好的做法是通过参数将值传入函数再通过return将结果传出来。6. 文件操作与异常处理与外界打交道程序不可能永远在内存里自娱自乐它需要从文件读取数据也需要把结果保存下来。同时外部世界充满不确定性文件不存在、网络错误、用户输入非法异常处理机制就是程序的“安全气囊”。6.1 文件的读写持久化存储Python使用open()函数打开文件它会返回一个文件对象。基本模式‘r’只读默认。文件必须存在。‘w’写入。如果文件存在则清空不存在则创建。‘a’追加。在文件末尾添加内容文件不存在则创建。‘x’创建新文件并写入如果文件已存在则失败。‘b’二进制模式例如‘rb’或‘wb’用于处理图片、视频等非文本文件。‘’读写模式与其他模式结合使用如‘r’。标准操作流程强烈推荐使用with语句# 写入文件 with open(‘example.txt’, ‘w’, encoding‘utf-8’) as file: file.write(“Hello, World!\n”) file.write(“This is a new line.\n”) # with语句块结束后文件会自动关闭无需手动调用file.close() # 读取整个文件内容 with open(‘example.txt’, ‘r’, encoding‘utf-8’) as file: content file.read() print(content) # 逐行读取处理大文件时常用 with open(‘example.txt’, ‘r’, encoding‘utf-8’) as file: for line in file: # 文件对象本身是可迭代的 print(line.strip()) # strip() 去掉每行末尾的换行符注意事项指定编码在打开文本文件时最好显式指定encoding参数如‘utf-8’尤其是在Windows系统或处理中文时可以避免乱码问题。文件路径可以使用相对路径相对于当前程序所在目录或绝对路径。如果文件路径包含特殊字符或空格建议使用原始字符串在引号前加r如open(r‘C:\Users\Name\Desktop\file.txt’, ‘r’)。‘w’模式会清空文件如果你只是想添加内容一定要用‘a’模式而不是‘w’模式否则原有内容会丢失。6.2 异常处理优雅地应对错误程序运行中难免出错比如打开不存在的文件、除零错误、类型转换失败等。Python使用try…except…else…finally结构来捕获和处理异常。try: # 尝试执行的代码 num int(input(“请输入一个整数: “)) result 10 / num print(f“结果是{result}”) except ValueError: # 如果发生ValueError例如输入的不是数字 print(“输入错误必须输入一个整数。”) except ZeroDivisionError: # 如果发生ZeroDivisionError除零错误 print(“错误不能除以零。”) except Exception as e: # 捕获所有其他未预料到的异常 print(f“发生了未知错误{e}”) else: # 如果没有发生任何异常执行这里的代码 print(“计算成功完成”) finally: # 无论是否发生异常最终都会执行这里的代码常用于清理资源如关闭文件 print(“程序执行结束。”)最佳实践具体异常优先先捕获你知道的、可能发生的具体异常如ValueError,FileNotFoundError最后再用通用的Exception兜底。不要滥用异常异常处理用于应对“异常”情况不要用它来代替正常的条件判断。例如检查一个键是否在字典中应该用if key in dict:而不是用try…except KeyError。记录异常信息在生产环境中除了给用户友好的提示还应该将异常的详细信息使用logging模块记录下来方便后期排查问题。7. 模块与包代码组织的进阶之道当你的代码越来越多把所有东西都写在一个文件里会变得难以维护。模块和包是Python组织代码的利器。7.1 模块Module一个.py文件就是一个模块模块就是一个包含Python定义和语句的.py文件。文件名就是模块名去掉.py后缀。你可以将相关的函数、类、变量组织在一个模块里。假设我们有一个名为my_utils.py的文件# my_utils.py def calculate_bmi(weight, height): “”“计算BMI指数”“” return weight / (height ** 2) def greet_user(name): return f“Welcome, {name}!” PI 3.14159在另一个文件中我们可以导入并使用这个模块# main.py # 方式1导入整个模块 import my_utils bmi my_utils.calculate_bmi(70, 1.75) print(my_utils.greet_user(“Alice”)) # 方式2从模块中导入特定函数/变量 from my_utils import calculate_bmi, PI bmi calculate_bmi(70, 1.75) # 现在可以直接使用函数名无需模块前缀 print(PI) # 方式3给模块起别名常用于长模块名 import my_utils as utils bmi utils.calculate_bmi(70, 1.75) # 方式4导入所有内容不推荐容易引起命名冲突 # from my_utils import *7.2 包Package包含多个模块的文件夹包是一个包含__init__.py文件可以是空文件的目录。包里面可以包含多个模块或子包用于组织更大型的项目。假设你的项目结构如下my_project/ │ ├── main.py │ └── my_package/ ├── __init__.py ├── module_a.py └── module_b.py你可以这样导入# 从包中导入模块 import my_package.module_a from my_package import module_b # 从包的模块中导入函数 from my_package.module_a import some_function__init__.py文件的作用它告诉Python这个目录是一个Python包。你可以在这个文件里写一些初始化代码或者定义__all__变量来控制from package import *时导入哪些模块。7.3 标准库与第三方库站在巨人的肩膀上Python强大的生态是其成功的关键。除了你自己写的模块还有标准库Python安装包自带的如处理日期的datetime、处理JSON的json、处理正则表达式的re等。直接import即可使用。第三方库由全球开发者贡献的需要通过包管理工具pip安装。例如数据分析的pandas、网络请求的requests、Web框架Django/Flask。使用pip安装第三方库在命令行中执行pip install requests然后在代码中导入import requests response requests.get(“https://api.example.com/data“) print(response.status_code)理解模块和包是你从写“脚本”迈向组织“项目”的关键一步。它让代码结构清晰易于协作和维护。当你开始一个稍大点的项目时第一件事就应该是规划好模块和包的结构。