简介:这是一份面向零基础与初学者的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得到"2test",a + int(d)得到1113,两条路径对应两种意图。
参数说明:int()只能转合法数字字符串,int("abc")会抛ValueError,实际项目里要包try/except;str()几乎什么都能转,但转完就是给人看的,别再拿去算数。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-1,end本身不包含在内,这是新手最常记反的地方。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 里长度一致,因为所有字符串都是 Unicode,len("你好")返回 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, b=2): 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 里是一等对象,可以当参数传、当返回值用。默认参数b=2让调用方可以少传一个参数,但默认值只在定义时求值一次,如果默认值是可变对象(列表、字典),多次调用会共享同一个对象,这是经典坑。
参数说明:range(1, 10)生成 1 到 9,不包含 10;range(-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默认自上而下,想自下而上用topdown=False。遍历时如果目录里有符号链接,默认不跟随,避免无限循环。
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_ok=True更稳;第二,shutil.copyfile遇到同名文件直接覆盖,备份场景里更安全的是先比对修改时间或大小;第三,getPathPrefix用字符串切片处理路径,跨平台时os.path.sep在 Windows 是反斜杠、Linux 是正斜杠,用os.path系列函数替代手写切片会更稳。
我自己的习惯是,任何备份脚本先拿一个几 MB 的测试目录跑一遍,确认目录结构对、文件数对、时间戳对,再指向真实数据。从那以后我每次写文件操作脚本,都强制先在临时目录走一遍全流程,确认没有路径拼接错误和覆盖风险,才敢碰真实目录。希望帮到你。
本文还有配套的精品资源,点击获取