Python入门经典实例:从基础语法到文件备份脚本实战 简介这是一份面向零基础与初学者的Python入门实例文档围绕输入输出、类型转换、列表、字典、字符串、注释与编码等核心基础展开帮助读者在动手实践中建立语法直觉与编程思维。资源包内含1个PDF文件大小约107KB内容以可运行的代码片段配合知识点注释呈现覆盖input与print用法、int与str转换、列表索引切片与增删、字典键值遍历、字符串不可变特性及UTF-8编码声明等典型场景便于边看边练、逐条对照理解。目前已有2021人学习下载适合刚接触Python、希望用短小实例快速熟悉常用数据结构与基础语法的读者也可作为课堂练习或自学入门的参考材料。1. 从一份 PDF 实例集说起Python 入门到底该练什么很多人学 Python 卡在同一个地方语法书翻了三遍if和for都认识但真给一个任务——把某个目录下的文件按日期备份、把字符串和数字拼起来打印、遍历嵌套文件夹——手就停在键盘上。问题不在智力在于缺一份「把最小可用知识点串成完整动作」的实例集。这份《Python 入门经典实例.pdf》就是干这个的它不讲语言史不铺陈设计哲学直接甩出 12 组可运行的小例子从input()收名字、列表切片、字典遍历一路推到文件复制、目录树遍历最后落在一个能跑的文件备份小程序上。适合谁适合已经看过一遍基础语法、但还没独立写过 50 行以上脚本的人也适合从 Java、JavaScript 转过来想快速摸清 Python 在字符串、缩进、模块路径上「哪里不一样」的熟手。它不教你成为高手它教你先把键盘敲热。2. 输入输出与类型转换先跑通第一个能交互的脚本2.1 从input()和print()开始建立反馈回路学任何语言第一件事是让程序「有反应」。这份实例集第 1 个例子就是收名字再打招呼代码短到可以背下来但里面藏了三个新手必踩的点编码声明、input()的返回值类型、print()的格式化方式。#! /usr/bin/python # -*- coding: utf8 -*- s1 input(Input your name:) print(你好, %s % s1) 知识点: * input(某字符串) 函数: 显示某字符串, 并等待用户输入. * print() 函数: 如何打印. * 如何应用中文 * 如何用多行注释 逻辑说明# -*- coding: utf8 -*-这行不是装饰是告诉解释器源文件按 UTF-8 解码。Python 3 默认源文件就是 UTF-8所以这行现在更多是习惯性保留但在读老代码或跨平台传文件时它仍然是排查乱码的第一线索。input()在 Python 3 里永远返回字符串哪怕你输入的是123拿到的也是123。print(你好, %s % s1)用的是百分号格式化%s是占位符后面用%把变量填进去。参数说明input()的参数是提示字符串会原样打印在等待输入的光标前print()可以接多个参数默认用空格分隔、末尾换行想改分隔符用sep想不换行用end。多行注释用三引号包裹实例里用它写知识点实际项目里更常见的是写函数说明。2.2 字符串和数字不能直接相加类型转换的边界第 2 个例子是整份文档里最值得反复看的一段因为它演示了一个从 JavaScript 转过来的人最容易翻车的地方。#! /usr/bin/python a 2 b test # c a b # 这行会报 TypeError c str(a) b # 把 int 转成 str 再拼接 d 1111 e a int(d) # 把 str 转成 int 再相加 print(c is %s, e is %i % (c, e)) 知识点: * 用 int 和 str 函数将字符串和数字进行转换 * 打印以 # 开头, 而不是习惯的 // * 打印多个参数的方式 逻辑说明Python 是强类型语言2 test不会像 JavaScript 那样偷偷把数字转成字符串而是直接抛TypeError。这不是设计缺陷是让你在拼接前想清楚「我要的是字符串结果还是数值结果」。str(a) b得到2testa int(d)得到1113两条路径对应两种意图。参数说明int()只能转合法数字字符串int(abc)会抛ValueError实际项目里要包try/exceptstr()几乎什么都能转但转完就是给人看的别再拿去算数。print里%s接字符串、%i接整数多个占位符要用元组(c, e)按顺序喂进去少一个参数会报TypeError多一个不会报错但会静默忽略——这个坑我见过有人在日志里漏打变量查了半天。提示如果你从 JavaScript 过来把「隐式转换」这个习惯先放下Python 里每一次类型变化都应该是你主动写的。3. 列表、字典与字符串三种容器的访问姿势和切片边界3.1 列表的索引、切片与增删第 3 个例子用word [a,b,c,d,e,f,g]把列表的常用操作几乎过了一遍。列表在 Python 里承担了 JavaScript 数组的角色但切片能力比 JS 的slice更顺手。#! /usr/bin/python # -*- coding: utf8 -*- word [a, b, c, d, e, f, g] a word[2] # 索引访问第三个元素 b word[1:3] # 索引 1 和 2 的元素 c word[:2] # 索引 0 和 1 的元素 d word[0:] # 全部元素 e word[:2] word[2:] # 切片合并等价于原列表 f word[-1] # 最后一个元素 g word[-4:-2] # 倒数第 4 到倒数第 3 个元素 h word[-2:] # 最后两个元素 i word[:-2] # 除最后两个外的全部 l len(word) print(Length of word is: str(l)) word.append(h) # 末尾追加 print(word) del word[0] # 删除指定索引 print(word) del word[1:3] # 删除切片范围 print(word)逻辑说明Python 索引从 0 开始负数索引从末尾倒着数-1是最后一个。切片word[start:end]取的是start到end-1end本身不包含在内这是新手最常记反的地方。word[:2] word[2:]拼起来等于原列表说明切片不会丢元素只是重新组合。参数说明append()一次只能加一个元素想加多个用extend()或del word[1:3]删除的是索引 1 和 2 两个元素删除后后面元素自动前移所以连续删除时索引会变别在循环里一边遍历一边del常见做法是倒着删或新建列表。3.2 字典遍历与字符串切片的一致性第 4 个例子把字典当 Java 的 Map 用第 5 个例子则强调「把字符串当列表来用」。这两块放在一起看能省掉很多重复记忆。#! /usr/bin/python x {a: aaa, b: bbb, c: 12} print(x[a]) print(x[b]) print(x[c]) for key in x: print(Key is %s and value is %s % (key, x[key]))逻辑说明字典用花括号定义键值对用冒号分隔。x[a]按键取值键不存在会抛KeyError实际项目里更稳的写法是x.get(a, 默认值)。for key in x遍历的是键要拿值就用x[key]Python 3.7 以后字典保持插入顺序所以遍历顺序是可预期的。字符串部分word abcdefg之后所有切片操作和列表完全一致word[2]、word[1:3]、word[-1]都成立。区别在于字符串不可变你不能word[0] z只能重新拼一个新字符串。参数说明len()对列表、字符串、字典都有效对字典返回键值对数量。中文和英文在 Python 3 里长度一致因为所有字符串都是 Unicodelen(你好)返回 2不会像某些语言那样按字节算成 6。注意切片越界不会报错word[1:100]会安静地返回从索引 1 到末尾的全部内容但索引访问越界会抛IndexError这两种行为要分清。4. 条件、循环、函数与异常把控制流写成能维护的样子4.1 缩进即语法条件和循环的写法差异第 6 个例子把if/elif/else和for循环放在一起顺带展示了input()配合int()的典型用法。#! /usr/bin/python x int(input(Please enter an integer:)) if x 0: x 0 print(Negative changed to zero) elif x 0: print(Zero) else: print(More) a [cat, window, defenestrate] for x in a: print(x, len(x))逻辑说明Python 不用花括号控制程序结构靠缩进。同一层级的语句缩进必须一致混用 Tab 和空格会报IndentationError这是新手最常见的翻车点之一。elif是 else if 的缩写可以接多个。for x in a直接遍历元素不需要索引需要索引时用enumerate(a)。参数说明int(input(...))是常见组合但用户输入非数字会抛ValueError生产代码要包异常处理。print(x, len(x))一次打印两个值默认空格分隔。4.2 函数默认参数与range()的步长第 7 个例子演示了函数定义、默认参数和range()的三种用法。#! /usr/bin/python # -*- coding: utf8 -*- def sum(a, b): return a b func sum r func(5, 6) print(r) def add(a, b2): return a b r add(1) print(r) r add(1, 5) print(r) a range(1, 10) for i in a: print(i) a range(-2, -11, -3) for i in a: print(i)逻辑说明函数用def定义return返回值。func sum把函数赋给变量说明函数在 Python 里是一等对象可以当参数传、当返回值用。默认参数b2让调用方可以少传一个参数但默认值只在定义时求值一次如果默认值是可变对象列表、字典多次调用会共享同一个对象这是经典坑。参数说明range(1, 10)生成 1 到 9不包含 10range(-2, -11, -3)从 -2 开始每次减 3到 -11 之前停止得到 -2、-5、-8。第三个参数是步长可以是负数但方向要和起止值匹配否则得到空序列。4.3 异常处理与文件读写第 8、9 个例子把异常和文件处理放在一起这是从「玩具脚本」走向「能干活」的分界线。#! /usr/bin/python s input(Input your age:) if s : raise Exception(Input must no be empty.) try: i int(s) except Exception as err: print(err) finally: print(Goodbye!)逻辑说明raise主动抛异常try/except/finally捕获并处理。finally里的代码无论是否出错都会执行适合放清理动作。捕获Exception是宽泛写法实际项目里更推荐捕获具体异常类型比如ValueError避免把不该吞的错误也吞掉。#! /usr/bin/python spath D:/download/baa.txt f open(spath, w) f.write(First line 1.\n) f.writelines(First line 2.) f.close() f open(spath, r) for line in f: print(每一行的数据是:%s % line) f.close()逻辑说明open()第二个参数w表示写会先清空文件内容r表示读a表示追加。write()写字符串writelines()写字符串序列但不会自动加换行要自己写\n。文件用完必须close()否则缓冲区内容可能没落盘。更稳的写法是用with open(...) as f:退出代码块自动关闭不用手动记。参数说明路径里的斜杠在 Windows 上写成D:/download/baa.txt或D:\\download\\baa.txt都行Python 能识别正斜杠。读文件时for line in f逐行迭代大文件也不会一次性吃满内存。5. 类、模块与包从单文件脚本到可复用结构5.1 类继承与self的含义第 10 个例子用Base和Child演示继承代码不长但把self和__init__讲清楚了。class Base: def __init__(self): self.data [] def add(self, x): self.data.append(x) def addtwice(self, x): self.add(x) self.add(x) class Child(Base): def plus(self, a, b): return a b oChild Child() oChild.add(str1) print(oChild.data) print(oChild.plus(2, 3))逻辑说明__init__是构造方法实例化时自动调用。self是实例本身的引用类似 Java 的this但 Python 要求你显式写在方法第一个参数位置。Child(Base)表示 Child 继承 Base自动获得add和addtwice方法同时可以定义自己的plus。参数说明self.data []在__init__里初始化保证每个实例有独立的列表如果写在类体里当类属性所有实例会共享同一个列表这是另一个经典坑。5.2 模块导入与包路径第 11 个例子讲模块和包这是很多人从「能跑」到「能组织」卡住的地方。# a.py def add_func(a, b): return a b # b.py from a import add_func print(Import add_func from module a) print(Result of 1 plus 2 is: ) print(add_func(1, 2))逻辑说明每个.py文件就是一个模块模块之间可以互相导入。from a import add_func只导入指定函数import a导入整个模块调用时要写a.add_func。包是带__init__.py的目录Python 靠这个文件识别目录为包。import sys import os sys.path.append(os.getcwd() \\parent\\child) print(sys.path) from a import add_func print(add_func(1, 2))逻辑说明sys.path是 Python 查找模块的路径列表把自定义目录追加进去Python 就能找到里面的模块。os.getcwd()拿当前工作目录拼出目标路径。另一种方式是把路径放进PYTHONPATH环境变量效果一样但改环境变量要重启终端。参数说明sys.path.append是运行时修改只在当前进程有效os.path.join比手拼字符串更稳能自动处理不同系统的路径分隔符。5.3 内建帮助与目录遍历第 12 个例子提到dir()和help()这是不查文档也能自救的两个函数。dir(list)列出列表所有方法help(list)打印详细说明。忘了某个方法名时先dir再help比翻网页快。文件遍历部分用os.walk返回三元组(parent, dirnames, filenames)parent是当前目录路径dirnames是子目录名列表filenames是文件名列表。os.path.join(parent, filename)拼出完整路径。os.path.split拆目录和文件名os.path.splitdrive拆盘符os.path.splitext拆扩展名这三个都返回二元组。import os import os.path rootdir d:/download for parent, dirnames, filenames in os.walk(rootdir): for dirname in dirnames: print(parent is: parent) print(dirname is: dirname) for filename in filenames: print(parent is: parent) print(filename with full path: os.path.join(parent, filename))逻辑说明os.walk自上而下遍历目录树每进入一个目录就产出一次三元组。dirnames和filenames都不含路径只有名字要完整路径必须用os.path.join拼。参数说明os.walk默认自上而下想自下而上用topdownFalse。遍历时如果目录里有符号链接默认不跟随避免无限循环。6. 避坑与排查这份实例集里最容易翻车的五个地方6.1 现象中文输出乱码或报SyntaxError: Non-UTF-8 code原因源文件编码和解释器读取编码不一致或者文件头没写编码声明。解决在文件第一行或第二行加# -*- coding: utf8 -*-并确认编辑器保存时选的是 UTF-8 而不是 GBK。如果还乱码检查终端编码Windows 老终端默认 GBK可以临时chcp 65001切到 UTF-8。6.2 现象TypeError: can only concatenate str (not int) to str原因字符串和数字直接用了。解决想拼字符串就str(a) b想算数就a int(d)。别指望 Python 隐式转换它不会。如果是从 JavaScript 转过来把这条当肌肉记忆练。6.3 现象IndentationError: unexpected indent或TabError原因缩进混用了 Tab 和空格或者同一层级缩进不一致。解决统一用 4 个空格编辑器里打开「显示空白字符」把 Tab 全部替换成空格。Python 官方风格指南推荐 4 空格别用 Tab。6.4 现象ModuleNotFoundError: No module named a原因模块不在sys.path里或者包目录缺__init__.py。解决确认a.py和当前脚本在同一目录或者用sys.path.append把目录加进去。包目录每一层都要有__init__.py内容可以为空但不能没有。6.5 现象shutil.copytree报FileExistsError原因目标目录已经存在copytree不会覆盖。解决复制前先判断目标是否存在存在就换名字或先删。实例里用try/except包住打印错误但不中断这是备份脚本里合理的容错方式。另外目标路径不能直接用盘符根目录会触发权限或路径问题。提示这五条里缩进和类型转换占了新手报错的一半以上先把这两条练成条件反射再去看后面的文件操作。7. 把实例串成一个能用的备份脚本参数、路径与时间戳实例集最后给了一个文件备份小程序把前面所有知识点串了起来os.walk遍历、shutil.copyfile复制、datetime生成时间戳、os.path处理路径。这段代码值得逐行拆开看因为它是从「学语法」到「写工具」的样板。import os import shutil import datetime def mainLogic(): backdir d:\\test copydirs [] copydirs.append(d:\\temp) start datetime.datetime.now() backdir os.path.join(backdir, start.strftime(%Y-%m-%d)) kc 0 for d in copydirs: kc kc copyFiles(d, backdir) end datetime.datetime.now() print(Finished! ) print(Total files : str(kc)) print(Elapsed time : str((end - start).seconds) seconds) def copyFiles(copydir, backdir): prefix getPathPrefix(copydir) i 0 for dirpath, dirnames, filenames in os.walk(copydir): for name in filenames: oldpath os.path.join(dirpath, name) newpath omitPrefix(dirpath, prefix) newpath os.path.join(backdir, newpath) if os.path.exists(newpath) ! True: os.makedirs(newpath) newpath os.path.join(newpath, name) shutil.copyfile(oldpath, newpath) i i 1 return i def getPathPrefix(fullpath): l fullpath.split(os.path.sep) if l[-1] : tmp l[-2] else: tmp l[-1] return fullpath[0:len(fullpath) - len(tmp) - 1] def omitPrefix(fullpath, prefix): return fullpath[len(prefix) 1:] mainLogic()逻辑说明mainLogic定义备份目的地和要备份的目录列表用datetime.now()拿当前时间strftime(%Y-%m-%d)格式化成日期字符串拼到备份根目录下这样每次备份自动分文件夹不会互相覆盖。copyFiles遍历源目录对每个文件算出相对路径在备份目录里建好对应子目录再shutil.copyfile复制。getPathPrefix和omitPrefix配合把源目录的父路径剥掉只保留相对结构。参数说明backdir改成你自己的备份根目录copydirs里 append 你要备份的目录可以加多个。strftime的格式串可以改成%Y-%m-%d_%H%M%S精确到秒避免同一天多次备份互相覆盖。shutil.copyfile只复制内容不复制权限和时间戳要保留元数据用shutil.copy2。几个可以立刻改进的点第一os.path.exists判断后os.makedirs有竞态多线程下可能重复建目录加exist_okTrue更稳第二shutil.copyfile遇到同名文件直接覆盖备份场景里更安全的是先比对修改时间或大小第三getPathPrefix用字符串切片处理路径跨平台时os.path.sep在 Windows 是反斜杠、Linux 是正斜杠用os.path系列函数替代手写切片会更稳。我自己的习惯是任何备份脚本先拿一个几 MB 的测试目录跑一遍确认目录结构对、文件数对、时间戳对再指向真实数据。从那以后我每次写文件操作脚本都强制先在临时目录走一遍全流程确认没有路径拼接错误和覆盖风险才敢碰真实目录。希望帮到你。本文还有配套的精品资源点击获取