| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Python知识库 -> Python学习笔记 -> 正文阅读 |
|
[Python知识库]Python学习笔记 |
时间2022.6.23 一.认识Python
章节简介:
1. Python 的起源
Python 是由 Guido van Rossum 在八十年代末和九十年代初,在荷兰国家数学和计算机科学研究所设计出来的。 Python 本身也是由诸多其他语言发展而来的,这包括 ABC、Modula-3、C、C++、Algol-68、SmallTalk、Unix shell 和其他的脚本语言等等。 像 Perl 语言一样,Python 源代码同样遵循 GPL(GNU General Public License)协议。 现在 Python 是由一个核心开发团队在维护,Guido van Rossum 仍然占据着至关重要的作用,指导其进展。 Python 2.0 于 2000 年 10 月 16 日发布,增加了实现完整的垃圾回收,并且支持 Unicode。 Python 3.0 于 2008 年 12 月 3 日发布,此版不完全兼容之前的 Python 源代码。不过,很多新特性后来也被移植到旧的Python 2.6/2.7版本。 Python 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。 Python 2.7 被确定为最后一个 Python 2.x 版本,它除了支持 Python 2.x 语法外,还支持部分 Python 3.1 语法。 (1)解释器(科普)计算机不能直接理解任何除机器语言以外的语言,所以必须要把程序员所写的程序语言翻译成机器语言,计算机才能执行程序。将其他语言翻译成机器语言的工具,被称为编译器 编译器翻译的方式有两种:一个是编译,另外一个是解释。两种方式之间的区别在于翻译时间点的不同。当编译器以解释方式运行的时候,也称之为解释器
编译型语言和解释型语言对比
(2)Python 的设计目标1999 年,吉多·范罗苏姆向 DARPA 提交了一条名为 “Computer Programming for Everybody” 的资金申请,并在后来说明了他对 Python 的目标:
这些想法中的基本都已经成为现实,Python 已经成为一门流行的编程语言 (3)Python 的设计哲学
<!-- > 在 Python 解释器内运行 `import this` 可以获得完整的列表 -->
2. 为什么选择 Python?
3. Python 特点
4. Python 的优缺点(1)优点
(2)缺点
5.Python 的主要运用领域有:
Python 在一些公司的运用有:
除此之外,还有搜狐、金山、腾讯、盛大、网易、百度、阿里、淘宝、土豆、新浪、果壳等公司正在使用 Python 来完成各种任务。 二.第一个 Python 程序1. 第一个HelloPython程序(1)Python 源程序的基本概念
(2)演练步骤目前的演示步骤是在Linux 终端 中实现的
print("hello python") print("hello world")
$ python 01-HelloPython.py
(3)BUG关于错误
第一个演练中的常见错误
NameError: name 'pirnt' is not defined ? 名称错误:'pirnt' 名字没有定义
SyntaxError: invalid syntax ? 语法错误:语法无效
IndentationError: unexpected indent ? 缩进错误:不期望出现的缩进
目前市场上有两个 Python 的版本并存着,分别是
SyntaxError: Non-ASCII character '\xe4' in file 01-HelloPython.py on line 3, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details ? 语法错误: 在 01-HelloPython.py 中第 3 行出现了非 ASCII 字符 '\xe4',但是没有声明文件编码 请访问 http://python.org/dev/peps/pep-0263/ 了解详细信息
单词列表: * error 错误 * name 名字 * defined 已经定义 * syntax 语法 * invalid 无效 * Indentation 索引 * unexpected 意外的,不期望的 * character 字符 * line 行 * encoding 编码 * declared 声明 * details 细节,详细信息 * ASCII 一种字符编码 2.Python 2.x与3??.x版本简介目前市场上有两个 Python 的版本并存着,分别是
3.执行 Python 程序的三种方式(1)解释器Python 的解释器 python/python3 # 使用 python 2.x 解释器 $ python xxx.py ? # 使用 python 3.x 解释器 $ python3 xxx.py 其他解释器(知道) Python 的解释器 如今有多个语言的实现,包括:
(2)交互式运行交互式运行Python程序
(例如在Linux虚拟机的终端中:) 1.优缺点 优点:
缺点:
2.退出 退出官方的解释器 1> 直接输入 >>> exit() 2> 使用热键退出 在 python 解释器中,按热键 3.IPython
特点
版本
1> 直接输入 In [1]: exit 2> 使用热键退出 在 IPython 解释器中,按热键 IPython 的安装(在乌班图中适用) $ sudo apt install ipython (3)IDE-PyCharm1.集成开发环境(IDE) 集成开发环境(
2.PyCharm 介绍
3.PyCharm 快速体验
4.Pyc 文件(了解)
字节码
三.PyCharm 的初始设置目标(仅了解,一下内容为在linux中运行提供备用参考)
PyCharm 的官方网站地址是:PyCharm: the Python IDE for Professional Developers by JetBrains 1. 恢复 PyCharm 的初始设置
如果要恢复
$ rm -r ~/.PyCharm2016.3
2.第一次启动 PyCharm
(1)导入配置信息
(2)选择许可协议
(3)PyCharm 的配置初始界面
(4)欢迎界面
3.新建/打开一个 Python 项目(1)项目简介
(2)打开 Python 项目
设置项目使用的解释器版本
(3)新建项目1.命名规则
2.演练步骤
4.设置 PyCharm 的字体显示5.PyCharm 的升级以及其他
(1)安装和启动步骤
$ tar -zxvf pycharm-professional-2017.1.3.tar.gz
$ sudo mv pycharm-2017.1.3/ /opt/
$ cd /opt/pycharm-2017.1.3/bin
$ ./pycharm.sh (2)设置专业版启动图标
(3)卸载之前版本的 PyCharm1.程序安装
2.程序卸载
$ sudo rm -r /opt/pycharm-2016.3.1/
$ rm -r ~/.PyCharm2016.3/
(4)教育版安装演练# 1. 解压缩下载后的安装包 $ tar -zxvf pycharm-edu-3.5.1.tar.gz # 2. 将解压缩后的目录移动到 `/opt` 目录下,可以方便其他用户使用 $ sudo mv pycharm-edu-3.5.1/ /opt/ # 3. 启动 `PyCharm` /opt/pycharm-edu-3.5.1/bin/pycharm.sh
设置启动图标
$ sudo gedit /usr/share/applications/jetbrains-pycharm.desktop
[Desktop Entry] Version=1.0 Type=Application Name=PyCharm Icon=/opt/pycharm-edu-3.5.1/bin/pycharm.png Exec="/opt/pycharm-edu-3.5.1/bin/pycharm.sh" %f Comment=The Drive to Develop Categories=Development;IDE; Terminal=false StartupWMClass=jetbrains-pycharm 6.多文件项目的演练
目标
多文件项目演练
提示
四.python基础学习1.注释目标
(1)注释的作用
(2)单行注释(行注释)
# 这是第一个单行注释 print("hello python")
在代码后面增加的单行注释
print("hello python") # 输出 `hello python` (3)多行注释(块注释)
""" 这是一个多行注释 在多行注释之间,可以写很多很多的内容…… """ print("hello python") 什么时候需要使用注释?
关于代码规范
2.运算符
(1)算数运算符
eg:
In [1]: "-" * 50 Out[1]: '----------------------------------------' 算数运算符的优先级
(2)比较(关系)运算符
(3)逻辑运算符
(4)赋值运算符
(5)运算符的优先级
其他身份运算符 身份运算符用于 比较 两个对象的 内存地址 是否一致 —— 是否是对同一个对象的引用
is 与 == 区别:
>>> a = [1, 2, 3] >>> b = [1, 2, 3] >>> b is a False >>> b == a True 3.变量
(1)定义
变量名 = 值
演练 1.演练—iPython(交互式) # 定义 qq_number 的变量用来保存 qq 号码 In [1]: qq_number = "1234567" # 输出 qq_number 中保存的内容 In [2]: qq_number Out[2]: '1234567' # 定义 qq_password 的变量用来保存 qq 密码 In [3]: qq_password = "123" # 输出 qq_password 中保存的内容 In [4]: qq_password Out[4]: '123'
2.演练—PyCharm(解释器) # 定义 qq 号码变量 qq_number = "1234567" # 定义 qq 密码变量 qq_password = "123" # 在程序中,如果要输出变量的内容,需要使用 print 函数 print(qq_number) print(qq_password)
3.变量—超市买苹果
需求
# 定义苹果价格变量 price = 8.5 # 定义购买重量 weight = 7.5 # 计算金额 money = price * weight print(money) (2)变量的类型1.变量类型
In [1]: type(name) eg: 2.不同类型变量之间的计算 (1)数字型变量之间可以直接计算
(2)字符串变量 之间使用
In [1]: first_name = "三" In [2]: last_name = "张" In [3]: first_name + last_name Out[3]: '三张' (3)字符串变量可以和 整数 使用 In [1]: "-" * 50 Out[1]: '--------------------------------------------------' (4)数字型变量和 字符串 之间 不能进行其他计算 In [1]: first_name = "zhang" In [2]: x = 10 In [3]: x + first_name --------------------------------------------------------------------------- TypeError: unsupported operand type(s) for +: 'int' and 'str' 类型错误:`+` 不支持的操作类型:`int` 和 `str` (3)变量的输入
1.input 函数实现键盘输入
字符串变量 = input("提示信息:") 2.类型转换函数
演练 变量输入演练 —— 超市买苹果增强版 需求
演练方式 1 # 1. 输入苹果单价 price_str = input("请输入苹果价格:") # 2. 要求苹果重量 weight_str = input("请输入苹果重量:") # 3. 计算金额 # 1> 将苹果单价转换成小数 price = float(price_str) # 2> 将苹果重量转换成小数 weight = float(weight_str) print("要支付的总金额为:") print(price * weight) 改进: price_str = float(input("请输出苹果的价格:")) weight_str = float(input("请输入苹果的单价:")) print("要支付的总金额为:") print(price_str * weight_str) (4)变量的格式化输出
print("格式化字符串" % 变量1) print("格式化字符串" % (变量1, 变量2...)) 知识点 对
# 向控制台输出内容结束之后,不会换行 print("*", end="") # 单纯的换行 print("")
假设 eg: 练习
name = "小明" print("我的名字叫%s,请多多关照" % name) student_no = 1 print("%06d" % student_no) price = 9 weight = 5 money = 45 print("苹果单价%.2f元/斤,购买了%.2f斤,需要支付%.2f元" % (price, weight, money)) scale = 0.1 print("%.2f%%" % (scale*100)) 练习 —— 个人名片
************************************************** 公司名称 姓名 (职位) 电话:电话 邮箱:邮箱 ************************************************** 实现代码如下: """ 在控制台依次提示用户输入:姓名、公司、职位、电话、电子邮箱 """ name = input("姓名:") company = input("公司:") company_position = input("职位:") telephone = input("电话:") mailbox = input("邮箱:") print("*" * 50) print(company) print("") print("%s(%s)" % (name, company_position)) print("") print("电话:%s" % telephone) print("邮箱:%s" % mailbox) print("*" * 50) (5)变量的命名1.标识符和关键字 标识符
eg: fromNo12 1(1对0错) from#12 0 my_Boolean 1 my-Boolean 0 Obj2 1 2ndObj 0 myInt 1 My_tExt 1 _test 1 test!32 0 haha(da)tt 0 jack_rose 1 jack&rose 0 GUI 1 G.U.I 0 关键字
通过以下命令可以查看 import keyword print(keyword.kwlist) D:\桌面\Pythoncode\venv\Scripts\python.exe D:/桌面/Pythoncode/test.py ['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield'] 进程已结束,退出代码0
2.变量的命名规则
注意
3.驼峰命名法
4.判断(if)语句(1)基本语法在 if 要判断的条件: 条件成立时,要做的事情 ……
我们可以把整个 if 语句看成一个完整的代码块 eg: age = 18 if age >= 18: print("可以进网吧嗨皮") 注意:
(2)else处理条件不满足的情况
if 要判断的条件: 条件成立时,要做的事情 …… else: 条件不成立时,要做的事情 …… 注意:
eg: # 1. 输入用户年龄 age = int(input("今年多大了?")) # 2. 判断是否满 18 岁 # if 语句以及缩进部分的代码是一个完整的语法块 if age >= 18: print("可以进网吧嗨皮……") else: print("你还没长大,应该回家写作业!") (3)elif
if 条件1: 条件1满足执行的代码 …… elif 条件2: 条件2满足时,执行的代码 …… elif 条件3: 条件3满足时,执行的代码 …… else: 以上条件都不满足时,执行的代码 …… 注意
演练 需求
holiday_name = str(input("请输入节日:")) if holiday_name == "情人节": print("买玫瑰/看电影") elif holiday_name == "平安夜": print("买苹果/吃大餐") elif holiday_name == "生日": print("买蛋糕") else: print("其他的日子每天都是节日啦!") (4)if 的嵌套
if 条件 1: 条件 1 满足执行的代码 …… if 条件 1 基础上的条件 2: 条件 2 满足时,执行的代码 …… # 条件 2 不满足的处理 else: 条件 2 不满足时,执行的代码 # 条件 1 不满足的处理 else: 条件1 不满足时,执行的代码 …… 演练 需求
knife_length = int(input("刀的长度cm(未携带输入:0):")) if has_ticket == "有": if knife_length <= 20: print("可以通过安检") else: print("刀的长度超过20cm,请上交后再进入") else: print("请购买车票后再进入") 5. 逻辑运算
(1)and条件1 and 条件2
(2)or条件1 or 条件2
(3)notnot 条件
演练
答案 1: # 练习1: 定义一个整数变量 age,编写代码判断年龄是否正确 age = int(input("请输入年龄:")) # if 0 <= age <= 120: if age >=0 and age <=120: print("您输入的年龄为%d,在0-120之间" % age) else: print("您输入的年龄为%d,不在0-120之间" % age) 答案 2: # 练习2: 定义两个整数变量 python_score、c_score,编写代码判断成绩 python_score = int(input("请输入您的Python成绩:")) c_score = int(input("请输入您的c成绩:")) if python_score >=60 or c_score >= 60: print("通过") else: print("继续努力") 答案 3: # 练习3: 定义一个布尔型变量 `is_employee`,编写代码判断是否是本公司员工 is_employee = True # 如果不是提示不允许入内 if not is_employee: print("非公勿内") 6.Random演练---石头剪刀布
import random
random.randint(12, 20) # 生成的随机数n: 12 <= n <= 20 random.randint(20, 20) # 结果永远是 20 random.randint(20, 10) # 该语句是错误的,下限必须小于上限 import random player = input("请输入石头/剪刀/布:") temp = int(random.randint(1, 3)) if temp == 1: print("电脑输入为:石头") elif temp == 2: print("电脑输入为剪刀") else: print("电脑输入为布") print("您输入为%s" % player) if player == "石头": player = 1 elif player == "剪刀": player = 2 else: player = 3 # 开始进入人机判断 if player == temp: print("平局") elif (temp - player) == 1 or (player - temp) == 2: print("玩家胜!") elif (temp - player) == 2 or (player - temp) == 1: print("电脑胜!") 7.循环语句(1)程序的三大流程
(2)while初始条件设置 —— 通常是重复执行的 计数器 while 条件(判断 计数器 是否达到 目标次数): 条件满足时,做的事情1 条件满足时,做的事情2 条件满足时,做的事情3 ...(省略)... 处理条件(计数器 + 1) 注意:
eg:打印 5 遍 Hello Python i = 0 while i < 5: i = i+1 print("Hello Python")
(3)循环计算
遇到这种需求,可以:
需求
# 计算 0 ~ 100 之间所有数字的累计求和结果 # 0. 定义最终结果的变量 result = 0 ? # 1. 定义一个整数的变量记录循环的次数 i = 0 ? # 2. 开始循环 while i <= 100: ? ? ?# 每一次循环,都让 result 这个变量和 i 这个计数器相加 ? ?result += i ? ? ?# 处理计数器 ? ?i += 1 ? print("0~100之间的数字求和结果 = %d" % result) ?
开发步骤
# 0. 最终结果 result = 0 # 1. 计数器 i = 0 # 2. 开始循环 while i <= 100: # 判断偶数 if i % 2 == 0: print(i) result += i # 处理计数器 i += 1 print("0~100之间偶数求和结果 = %d" % result) (4)break/continue
1.break
i = 0 while i < 10: # break 某一条件满足时,退出循环,不再执行后续重复的代码 # i == 3 if i == 3: break print(i) i += 1 print("over")
2.continue
i = 0 while i < 10: # 当 i == 7 时,不希望执行需要重复执行的代码 if i == 7: # 在使用 continue 之前,同样应该修改计数器 # 否则会出现死循环 i += 1 continue # 重复执行的代码 print(i) i += 1
(5)while循环嵌套####
while 条件 1: 条件满足时,做的事情1 条件满足时,做的事情2 条件满足时,做的事情3 ...(省略)... while 条件 2: 条件满足时,做的事情1 条件满足时,做的事情2 条件满足时,做的事情3 ...(省略)... 处理条件 2 处理条件 1 演练 1.用嵌套打印小星星 eg: temp = 1 while temp <=5: print("*"*temp) temp = temp + 1 * ** *** **** ***** 2.九九乘法表 m = 1 # 行数 n = 1 # 列数 while n <= 9: while m <= n: print("%d * %d = %d" % (m, n, m * n), end=" ") m = m + 1 print(" ") m = 1 n = n + 1 8.函数基础(1)函数基本使用1)定义
定义函数的格式如下: def 函数名(): 函数封装的代码 ……
2)调用 通过 eg: def say_hello(): print("hello1") print("hello2") print("hello3") say_hello()
注意
(2)函数的参数1)函数参数的使用
def sum(num1, num2): result = num1 + num2 print("%d + %d = %d" % (num1, num2, result)) sum(10, 20) 2)参数的作用
3)形参和实参
(3)函数的返回值
def sum_2_num(num1, num2): """对两个数字的求和""" return num1 + num2 # 调用函数,并使用 result 变量接收计算结果 result = sum_2_num(10, 20) print("计算结果是 %d" % result) (4)函数的嵌套调用
def test1(): print("*" * 50) print("test 1") print("*" * 50) def test2(): print("-" * 50) print("test 2") test1() print("-" * 50) test2() 演练 需求 1
def print_line(char): print("*" * 50) 需求 2
def print_line(char): print(char * 50) 需求 3
def print_line(char, times): print(char * times) 需求 4
def print_line(char, times): print(char * times) def print_lines(char, times): temp = 0 while temp < 5: print_line(char, times) temp += 1 print_lines("*", 5) (5)使用模块中的函数
eg: 注意:模块名也是一个标识符
9.列表(1)定义
创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可。如下所示: list1 = ['Google', 'Runoob', 1997, 2000] list2 = [1, 2, 3, 4, 5 ] list3 = ["a", "b", "c", "d"] list4 = ['red', 'green', 'blue', 'yellow', 'white', 'black'] name_list = ["zhangsan", "lisi", "wangwu"] (2)访问列表的值与字符串的索引一样,列表索引从 0 开始,第二个索引是 1,依此类推。 通过索引列表可以进行截取、组合等操作。 eg: name = ['red', 'green', 'blue', 'yellow', 'white', 'black'] print(name[0]) print(name[1]) print(name[2]) 以上实例输出结果: red green blue 注意:索引也可以从尾部开始,最后一个元素的索引为 -1,往前一位为 -2,以此类推。 eg: name = ['red', 'green', 'blue', 'yellow', 'white', 'black'] print(name[-6]) print(name[-5]) print(name[-4]) 以上实例输出结果: black white yellow 使用下标索引来访问列表中的值,同样你也可以使用方括号 [] 的形式截取字符,如下所示: nums = [10, 20, 30, 40, 50, 60, 70, 80, 90] print(nums[0:4]) 以上实例输出结果: [10, 20, 30, 40] 使用负数索引值截取: eg: list = ['Google', 'Runoob', "Zhihu", "Taobao", "Wiki"] # 读取第二位 print("list[1]: ", list[1]) # 从第二位开始(包含)截取到倒数第二位(不包含) print("list[1:-2]: ", list[1:-2]) 以上实例输出结果: list[1]: Runoob list[1:-2]: ['Runoob', 'Zhihu'] (3)修改你可以对列表的数据项进行修改或更新,你也可以使用 append() 方法来添加列表项,如下所示: print("第三个元素为 : ", name[2]) name[2] = 2001 print("更新后的第三个元素为 : ", name[2]) 第三个元素为 : 1997 更新后的第三个元素为 : 2001 (4)增加1)append() append() 方法用于在列表末尾添加新的对象,是指在列表末尾增加一个数据项。 append()方法语法: list.append(obj)
eg: list1 = ['Google', 'Runoob', 'Taobao'] list1.append('Baidu') print ("更新后的列表 : ", list1) 以上实例输出结果如下: 更新后的列表 : ['Google', 'Runoob', 'Taobao', 'Baidu'] 在append中也可以添加列表 eg: 2)extend extend()方法是指在列表末尾增加一个数据集合 list1 = ['Google', 'Taobao'] list2 = ['QQ', 'Wechat'] list1.extend() print("更新后的列表 : ", list1) 但是extend与append的主要区别是 eg1: eg2: 3)insert 列表.insert(索引, 数据)---在指定位置插入数据 list1 = ['Google', 'Taobao'] list1.insert(1, 'Wechat') print("更新后的列表 : ", list1) 更新后的列表 : ['Google', 'Wechat', 'Taobao'] (5)删除1)del del(关键字)可以使用 del 语句来删除列表的的元素,如下实例: list = ['张三', '李四', '王五', '赵六'] print("原始列表: ", list) del list[2] print("删除第三个元素: ", list) 以上实例输出结果: 原始列表 : ['Google', 'Runoob', 1997, 2000] 删除第三个元素 : ['Google', 'Runoob', 2000] del的本质上是用来将一个变量从内存中删除
如果使用del关键字删除一个变量,那么在后续的代码中就不能再使用这个变量了 2)remove remove可以删除列表中的指定数据 list = ['张三', '李四', '王五', '赵六'] print("原始列表: ", list) list.remove('王五') print("删除第三个元素: ", list) 3)pop pop方法默认可以把列表中最后一个元素删除 list = ['张三', '李四', '王五', '赵六'] print("原始列表: ", list) list.pop() print("删除后: ", list) 原始列表: ['张三', '李四', '王五', '赵六'] 删除后: ['张三', '李四', '王五'] 也可以指定要删除元素的索引 list = ['张三', '李四', '王五', '赵六'] print("原始列表: ", list) list.pop(3) print("删除第三个元素: ", list) 原始列表: ['张三', '李四', '王五', '赵六'] 删除第三个元素: ['张三', '李四', '王五'] 4)clear clear方法可以清空列表 list = ['张三', '李四', '王五', '赵六'] print("原始列表: ", list) list.clear() print("删除后: ", list) 原始列表: ['张三', '李四', '王五', '赵六'] 删除后: [] (6)统计1)len 函数可以统计列表中元素的个数 list = ['张三', '李四', '王五', '赵六'] length = len(list) print("列表中共有 %d 个元素" % len(list)) 列表中共有 4 个元素 2)count 方法可以统计列表中某一个数据出现的次数 list = ['张三', '李四', '王五', '赵六', '张三', '张三'] print("列表中 张三 一共出现了 %d 次" % list.count("张三")) 列表中 张三 一共出现了 3 次 (7)排序1)sort升序 name_list = ['zhangsan', 'lisi', 'wangwu', 'zhaoliv'] num_list = [6, 8, 4, 5, 1] print("排序前:%s" % name_list) print("排序前:%s" % num_list) name_list.sort() num_list.sort() print("排序前:%s" % name_list) print("排序后:%s" % num_list) 排序前:['zhangsan', 'lisi', 'wangwu', 'zhaoliv'] 排序前:[6, 8, 4, 5, 1] 排序前:['lisi', 'wangwu', 'zhangsan', 'zhaoliv'] 排序后:[1, 4, 5, 6, 8] 2)sort(reverse=True)降序 name_list = ['zhangsan', 'lisi', 'wangwu', 'zhaoliv'] num_list = [6, 8, 4, 5, 1] print("排序前:%s" % name_list) print("排序前:%s" % num_list) name_list.sort(reverse=True) num_list.sort(reverse=True) print("排序前:%s" % name_list) print("排序后:%s" % num_list) 排序前:['zhangsan', 'lisi', 'wangwu', 'zhaoliv'] 排序前:[6, 8, 4, 5, 1] 排序前:['zhaoliv', 'zhangsan', 'wangwu', 'lisi'] 排序后:[8, 6, 5, 4, 1] 如果把True改成False时便成了升序 3)reverse name_list = ['zhangsan', 'lisi', 'wangwu', 'zhaoliv'] num_list = [6, 8, 4, 5, 1] print("排序前:%s" % name_list) print("排序前:%s" % num_list) name_list.reverse() num_list.reverse() print("排序前:%s" % name_list) print("排序后:%s" % num_list) 排序前:['zhangsan', 'lisi', 'wangwu', 'zhaoliv'] 排序前:[6, 8, 4, 5, 1] 排序前:['zhaoliv', 'wangwu', 'lisi', 'zhangsan'] 排序后:[1, 5, 4, 8, 6] (8)列表脚本操作符列表对 + 和 * 的操作符与字符串相似。+ 号用于组合列表,* 号用于重复列表。 如下所示:
in 迭代遍历
格式如下: # for 循环内部使用的变量 in 列表 for name in name_list: 循环内部针对列表元素进行操作 print(name) 方法一: name_list = ['zhangsan', 'lisi', 'wangwu', 'zhaoliv'] for name in name_list: print(name) zhangsan lisi wangwu zhaoliv 方法二: for x in [1, 2, 3]: print(x, end=" ") 1 2 3 (9)列表截取与拼接Python的列表截取与字符串操作类型,如下所示: L=['Google', 'Runoob', 'Taobao'] 操作:
L=['Google', 'Runoob', 'Taobao'] print(L[2]) print(L[1:]) print(L[-2]) Taobao ['Runoob', 'Taobao'] Runoob 列表还支持拼接操作: squares = [1, 4, 9, 16, 25] squares += [36, 49, 64, 81, 100] print(squares) [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] (10)常用操作总结
In [1]: name_list. name_list.append name_list.count name_list.insert name_list.reverse name_list.clear name_list.extend name_list.pop name_list.sort name_list.copy name_list.index name_list.remove
10. 元组(1)元组的定义
info_tuple = ("zhangsan", 18, 1.75) 创建空元组 info_tuple = () 元组中 只包含一个元素 时,需要 在元素后面添加逗号 info_tuple = (50, ) 关于元组是不可变的 所谓元组的不可变指的是元组所指向的内存中的内容不可变。 从以上实例可以看出,重新赋值的元组 tup,绑定到新的对象了,不是修改了原来的对象。 (2)访问元组元组可以使用下标索引来访问元组中的值,如下实例: tup1 = ('Google', 'Runoob', 1997, 2000) tup2 = (1, 2, 3, 4, 5, 6, 7) print("tup1[0]: ", tup1[0]) print("tup2[1:5]: ", tup2[1:5]) 以上实例输出结果: tup1[0]: Google tup2[1:5]: (2, 3, 4, 5) (3)修改元组元组中的元素值是不允许修改的,但我们可以对元组进行连接组合,如下实例: tup1 = (12, 34.56) tup2 = ('abc', 'xyz') # 以下修改元组元素操作是非法的。 # tup1[0] = 100 # 创建一个新的元组 tup3 = tup1 + tup2 print(tup3) 以上实例输出结果: (12, 34.56, 'abc', 'xyz') (4)删除元组元组中的元素值是不允许删除的,但我们可以使用del语句来删除整个元组,如下实例: tup = ('Google', 'Runoob', 1997, 2000) print(tup) del tup print("删除后的元组 tup : ") print(tup) 以上实例元组被删除后,输出变量会有异常信息,输出如下所示: 删除后的元组 tup : Traceback (most recent call last): File "test.py", line 8, in <module> print (tup) NameError: name 'tup' is not defined (5)运算符与字符串一样,元组之间可以使用 + 号和 * 号进行运算。这就意味着他们可以组合和复制,运算后会生成一个新的元组。
(6)内置函数Python元组包含了以下内置函数
(7)元组可以使用的函数
info.count info.index
(8)循环遍历
# for 循环内部使用的变量 in 元组 for item in info: 循环内部针对元组元素进行操作 print(item) tup = (1, 2, 3, 4, 5) for item in tup: print(item) 1 2 3 4 5
(9)应用场景
info = ("zhangsan", 18) ? print("%s 的年龄是 %d" % info) ? (10)元组和列表之间的转换
list(元组)
tuple(列表) 11.字典(1)定义
d = {key1 : value1, key2 : value2, key3 : value3 } eg: xiaoming = {"name": "小明", "age": 18, "gender": True, "height": 1.75} {'name': '小明', 'age': 18, 'gender': True, 'height': 1.75} 注意: dict 作为 Python 的关键字和内置函数,变量名不建议命名为 dict。 (2)常用操作
In [1]: xiaoming. xiaoming.clear xiaoming.items xiaoming.setdefault xiaoming.copy xiaoming.keys xiaoming.update xiaoming.fromkeys xiaoming.pop xiaoming.values xiaoming.get xiaoming.popitem
1)访问值 把相应的键放入到方括号中,如下实例: xiaoming = {"name": "小明", "age": 18, "gender": True, "height": 1.75} print("xiaoming['name']: ", xiaoming['name']) print("xiaoming['age']: ", xiaoming['age']) 以上实例输出结果: xiaoming['name']: 小明 xiaoming['age']: 18 如果用字典里没有的键访问数据,会输出错误如下: xiaoming = {"name": "小明", "age": 18, "gender": True, "height": 1.75} print("xiaoming['name']: ", xiaoming['name123']) print("xiaoming['age']: ", xiaoming['age']) 以上实例输出结果: Traceback (most recent call last): File "D:\桌面\Pythoncode\Test.py", line 6, in <module> print("xiaoming['name']: ", xiaoming['name123']) KeyError: 'name123' 2)修改字典 向字典添加新内容的方法是增加新的键/值对,修改或删除已有键/值对如下实例: (如果新内容键值不存在----新增,存在---修改) 新增: xiaoming_dict = {"name": "小明"} xiaoming_dict["age"] = 12, 18 print(xiaoming_dict) 以上实例输出结果: {'name': '小明', 'age': (12, 18)} 修改: xiaoming_dict = {"name": "小明"} xiaoming_dict["age"] = 12 xiaoming_dict["name"] = "小小明" print(xiaoming_dict) 以上实例输出结果: {'name': '燕小明', 'age': 12} 3)删除字典元素 能删单一的元素也能清空字典,清空只需一项操作。 显式删除一个字典用del命令,如下实例: xiaoming_dict = {"name": "小明"} del xiaoming_dict print(xiaoming_dict) 但这会引发一个异常,因为用执行 del 操作后字典不再存在: Traceback (most recent call last): File "D:\桌面\Pythoncode\Test.py", line 4, in <module> print(xiaoming_dict) NameError: name 'xiaoming_dict' is not defined 删除指定键pop xiaoming_dict = {"name": "小明", "age":18} xiaoming_dict.pop("name") print(xiaoming_dict) {'age': 18} 如果指定删除的键不存在程序会报错 4)内置函数&方法 Python字典包含了以下内置函数:
Python字典包含了以下内置方法:
演示: len计算字典元素个数 xiaoming_dict = {"name": "小明", "age":18} print(len(xiaoming_dict)) 2 update合并字典 test_one = {"name": "小明"} test_two = {"age": 16} test_one.update(test_two) print(test_one) {'name': '小明', 'age': 16} 合并键值对中键值对重复,覆盖原有的键值对 test_one = {"name": "小明", "age":18} test_two = {"name": "小王", "age":16} test_one.update(test_two) print(test_one) {'name': '小王', 'age': 16} 5)字典键的特性 字典值可以是任何的 python 对象,既可以是标准的对象,也可以是用户定义的,但键不行。 两个重要的点需要记住: (1)不允许同一个键出现两次。创建时如果同一个键被赋值两次,后一个值会被记住,如下实例: test_one = {"name": "小明", "age": 18, "name": "小王" } print(test_one) {'name': '小王', 'age': 18} (2)键必须不可变,所以可以用数字,字符串或元组充当,而用列表就不行,如下实例: test_one = {['name']: '小明', 'age': 18} print("test_one['name']: ", test_one['name']) 以上实例输出结果: Traceback (most recent call last): File "D:\桌面\Pythoncode\Test.py", line 1, in <module> test_one = {['name']: '小明', 'age': 18} TypeError: unhashable type: 'list' 6)循环遍历
test_one = {"name": "小明", "age": "18", "phone": "10086"} for k in test_one: print("%s: %s" % (k, test_one[k]))
7)应用场景
card_list = [{"name": "张三", "qq": "12345", "phone": "110"}, {"name": "李四", "qq": "54321", "phone": "10086"} ] for k in card_list: print(k) {'name': '张三', 'qq': '12345', 'phone': '110'} {'name': '李四', 'qq': '54321', 'phone': '10086'} 12.字符串(1)定义
string = "Hello Python" for c in string: print(c) 在Python2中,普通字符串是以8位ASCII码进行存储的,而Unicode字符串则存储为16位unicode字符串,这样能够表示更多的字符集。使用的语法是在字符串前面加上前缀 u。 在Python3中,所有的字符串都是Unicode字符串。 (2)转义字符在需要在字符中使用特殊字符时,python 用反斜杠 ** 转义字符。如下表:
(3)常用操作
In [1]: hello_str. hello_str.capitalize hello_str.isidentifier hello_str.rindex hello_str.casefold hello_str.islower hello_str.rjust hello_str.center hello_str.isnumeric hello_str.rpartition hello_str.count hello_str.isprintable hello_str.rsplit hello_str.encode hello_str.isspace hello_str.rstrip hello_str.endswith hello_str.istitle hello_str.split hello_str.expandtabs hello_str.isupper hello_str.splitlines hello_str.find hello_str.join hello_str.startswith hello_str.format hello_str.ljust hello_str.strip hello_str.format_map hello_str.lower hello_str.swapcase hello_str.index hello_str.lstrip hello_str.title hello_str.isalnum hello_str.maketrans hello_str.translate hello_str.isalpha hello_str.partition hello_str.upper hello_str.isdecimal hello_str.replace hello_str.zfill hello_str.isdigit hello_str.rfind
1)访问字符串中的值 Python 不支持单字符类型,单字符在 Python 中也是作为一个字符串使用。 Python 访问子字符串,可以使用方括号 [] 来截取字符串,字符串的截取的语法格式如下: 变量[头下标:尾下标] 索引值以 0 为开始值,-1 为从末尾的开始位置。 如下实例: var1 = 'Hello World!' var2 = "123456" print("var1[0]: ", var1[0]) print("var2[1:5]: ", var2[1:5]) 以上实例执行结果: var1[0]: H var2[1:5]: 2345 2)统计长度/次数/位置 1.统计字符串长度 hello_str = "hello hello" print(len(hello_str)) 11 2.统计某一个小字符串出现的次数 hello_str = "hello hello" print(hello_str.count("llo")) 2 3.某一个子字符串出现的位置 hello_str = "hello hello" print(hello_str.index("llo")) 2 如果使用index方法传递的子字符串不存在,程序会报错 3) 判断类型
(1)ispace 如果 string 中只包含空格,则返回 True 注意:这里的空格还包括:\n \v \t \r \f hello_str = "\n \v \t \r \f" print(hello_str.isspace()) True (2)isdecimal / isdigit / isnumeric 1.都不能判断小数 num_str = "1.1" print(num_str) print(num_str.isdecimal()) print(num_str.isdigit()) print(num_str.isnumeric()) 1.1 False False False 2.特殊符号后两个可以判断 eg1: num_str = "⑴" print(num_str) print(num_str.isdecimal()) print(num_str.isdigit()) print(num_str.isnumeric()) ⑴ False True True eg2: num_str = "\u00b2" print(num_str) print(num_str.isdecimal()) print(num_str.isdigit()) print(num_str.isnumeric()) 2 False True True 3.中文汉字仅最后一个可以判断 num_str = "一千零一" print(num_str) print(num_str.isdecimal()) print(num_str.isdigit()) print(num_str.isnumeric()) 一千零一 False False True 故在开发时建议使用isdecimal方法 4) 查找和替换
(1)startswith 检查字符串是否是以指定 str 开头,是则返回 True hello_str = "hello" print(hello_str.startswith("hello")) True 在python中是区分大小写的 hello_str = "hello" print(hello_str.startswith("hello")) False (2)endwith 检查字符串是否是以指定 str 结束,是则返回 True hello_str = "hello world" print(hello_str.endswith("world")) True 同样也是区分大小写的 hello_str = "hello world" print(hello_str.endswith("World")) False (3)find 检测 str 是否包含在 string 中,如果 start 和 end 指定范围,则检查是否包含在指定范围内,如果是返回开始的索引值,否则返回 hello_str = "hello world" print(hello_str.find("llo")) print(hello_str.find("abc")) 2 -1 index同样也可以查找指定的字符串在大字符中的索引,但是在index中指定字符串不存在会报错,而find中不存在会返回-1 (4)replace 把 string 中的 old_str 替换成 new_str,如果 num 指定,则替换不超过 num 次 replace方法执行完成之后,会返回一个新的字符串,但不会修改原有字符串的内容 hello_str = "hello world" print(hello_str.replace("world", "python")) print(hello_str) hello python hello world 5) 大小写转换
6) 文本对齐
(1)ljust左对齐 poem = ["登鹳雀楼", "王之涣 ", "白日依山尽,", "黄河入海流。", "欲穷千里目,", "更上一层楼。"] for pome_str in poem: print("|%s|" % pome_str.ljust(10, " ")) |登鹳雀楼 | |王之涣 | |白日依山尽, | |黄河入海流。 | |欲穷千里目, | |更上一层楼。 | (2)rjust右对齐 poem = ["登鹳雀楼", "王之涣 ", "白日依山尽,", "黄河入海流。", "欲穷千里目,", "更上一层楼。"] for pome_str in poem: print("|%s|" % pome_str.rjust(10, "")) | 登鹳雀楼| | 王之涣 | | 白日依山尽,| | 黄河入海流。| | 欲穷千里目,| | 更上一层楼。| (3)center居中 poem = ["登鹳雀楼", "王之涣 ", "白日依山尽,", "黄河入海流。", "欲穷千里目,", "更上一层楼。"] for pome_str in poem: print("|%s|" % pome_str.center(10)) 注: print("|%s|" % pome_str.center(10, " ")) 也可以这样输出,默认的是英文空格,也可以插入中文空格或者 \t | 登鹳雀楼 | | 王之涣 | | 白日依山尽, | | 黄河入海流。 | | 欲穷千里目, | | 更上一层楼。 | 7) 去除空白字符
poem = ["\t\n登鹳雀楼", "王之涣 ", "白日依山尽,\t\n", "黄河入海流。", "欲穷千里目,", "更上一层楼。"] for pome_str in poem: print("|%s|" % pome_str.strip().center(10)) | 登鹳雀楼 | | 王之涣 | | 白日依山尽, | | 黄河入海流。 | | 欲穷千里目, | | 更上一层楼。 | 8) 拆分和连接
(1)拆分字符串 poem = "登鹳雀楼\t 王之涣 \t 白日依山尽 \t\n 黄河入海流 \t \t\n 欲穷千里目 \t 更上一层楼" poem_list = poem.split() print(poem_list) ['登鹳雀楼', '王之涣', '白日依山尽', '黄河入海流', '欲穷千里目', '更上一层楼'] (2)合并字符串 poem = "登鹳雀楼\t 王之涣 \t 白日依山尽 \t\n 黄河入海流 \t \t\n 欲穷千里目 \t 更上一层楼" poem_list = poem.split() print(poem_list) result = " ".join(poem_list) print(result) ['登鹳雀楼', '王之涣', '白日依山尽', '黄河入海流', '欲穷千里目', '更上一层楼'] 登鹳雀楼 王之涣 白日依山尽 黄河入海流 欲穷千里目 更上一层楼 (4)字符串的切片
字符串[开始索引:结束索引:步长] 注意:
索引的顺序和倒序
演练
答案 num_str = "0123456789" # 1.截取2-5位置的字符串 print(num_str[2:6]) # 2.截取2-末尾位置的字符串 print(num_str[2:]) # 3.截取从开始到5位置的字符串 print(num_str[:6]) print(num_str[0:6]) # 4.截取完整字符 print(num_str[:]) # 5.每隔一个字符串截取一个字符 print(num_str[::2]) # 6.索引从1开始每隔一个字符串截取一个字符 print(num_str[1::2]) # 7.截取从2到-1的字符串 print(num_str[2:-1]) # 8.截取末尾两个字符串 print(num_str[-2:]) # 9.通过切片获取字符串的逆序 print(num_str[-1::-1]) 13.公共方法公共方法------列表,元组,字符串(高级数据类型)都可以使用的方法为 1)Python 内置函数内置函数------不需要通过使用import关键字导入任何模块就可以通过函数名直接调用的函数 Python 包含了以下内置函数:
eg: num_list = [1, 2, 3, 4, 8, 9] print(len(num_list)) print(min(num_list)) print(max(num_list)) 6 1 9 *注意**
2)切片
eg: num_list = [1, 2, 3, 4, 8, 9] print(num_list[0::2]) num_lists = (1, 2, 3, 4, 8, 9) print(num_lists[0::2]) [1, 3, 8] (1, 3, 8) 3)运算符
+ print("Hello" + "Python") HelloPython * print("Hello "*3) Hello Hello Hello in print("a" in "abc") True not in print("a" not in "abc") False 注意
成员运算符 成员运算符用于 测试 序列中是否包含指定的 成员
注意:在对 字典 操作时,判断的是 字典的键 4)完整的 for 循环语法
for 变量 in 集合: 循环体代码 else: 没有通过 break 退出循环,循环结束后,会执行的代码 应用场景
eg: for num in [1,2,3]: print(num) else: print("会执行嘛") print("循环结束") 1 2 3 会执行嘛 循环结束 eg: for num in [1,2,3]: print(num) if num ==2: break else: print("会执行嘛") print("循环结束") 1 2 循环结束 students = [ {"name": "阿土", "age": 20, "gender": True, "height": 1.7, "weight": 75.0}, {"name": "小美", "age": 19, "gender": False, "height": 1.6, "weight": 45.0}, ] find_name = "阿土" for stu_dict in students: print(stu_dict) # 判断当前遍历的字典中姓名是否为find_name if stu_dict["name"] == find_name: print("找到了") # 如果已经找到,直接退出循环,就不需要再对后续的数据进行比较 break else: print("没有找到") print("循环结束") {'name': '阿土', 'age': 20, 'gender': True, 'height': 1.7, 'weight': 75.0} 找到了 循环结束 综合应用---名片管理系统综合应用已经学习过的知识点:
开发 名片管理系统 系统需求:
************************************************** 欢迎使用【名片管理系统】V1.0 1. 新建名片 2. 显示全部 3. 查询名片 0. 退出系统 **************************************************
cards_main.py import cards_tools while True: # 显示功能菜单 cards_tools.show_menu() action_str = input("请您选择希望执行的操作:\n") if action_str in ["1", "2", "3"]: # 1. 新建名片 if action_str == "1": cards_tools.new_card() # 2. 显示全部 elif action_str == "2": cards_tools.show_all() # 3. 查询名片 elif action_str == "3": cards_tools.search_card() elif action_str == "0": print("欢迎再次使用【名片管理系统】") # 在开发时,不希望立即编写分支内部的代码 # 或者这里不输出提示语句时,应用到 pass 关键字,表示一个占位符,能保证程序代码的结构正确 # 程序运行时,pass关键字不会执行任何操作 break else: print("您输入的不正确,请重新输入") cards_tools.py # 记录所有名片字典 card_list = [] def show_menu(): """显示菜单""" print("*" * 50) print("迎使用【名片管理系统】V1.0") print("1. 新建名片") print("2. 显示全部") print("3. 查询名片") print("0. 退出系统") print("*" * 50) def new_card(): """新增名片""" print("-" * 50) print("新增名片") # 1.提示用户输入名片的详细信息 name_str = input("请输入姓名:") phone_str = input("请输入电话:") qq_str = input("请输入QQ号码:") email_str = input("请输入邮箱号码:") # 2.使用用户输入的信息建立一个名片字典 card_dict = {"name": name_str, "phone": phone_str, "qq": qq_str, "email": email_str} # 3.将名片字典添加到列表中 card_list.append(card_dict) print(card_list) # 4.提示用户添加成功 print("添加 %s 的名片成功!" % name_str) def show_all(): """显示所有名片""" print("-" * 50) print("显示所有名片") # 判断是否存在名片记录,如果没有,提示用户并且返回 if len(card_list) == 0: print("当前没有任何名片记录,请使用新增功能添加名片!") # return 可以反hi一个函数的执行结果 # 下方的代码不会执行 # 如果return后面没有任何内容,便是会返回到调用函数的位置,并且不能返回任何结果 return # 打印表头 for name in ["姓名", "电话", "QQ ", "邮箱"]: print(name, end="\u3000\t\t") print("") # 打印分割线 print("=" * 50) # 遍历名片列表依次输出字典信息 for card_dict in card_list: print("%s\u3000\t\t%s\u3000\t\t%s\u3000\t\t%s\u3000\t\t" % (card_dict["name"], card_dict["phone"], card_dict["qq"], card_dict["email"])) def search_card(): """搜索名片""" print("-" * 50) print("搜索名片") # 1.提示用户输入要搜索的姓名 find_name = input("请输入要搜素的姓名:") # 2.遍历名片列表,查询要搜索的姓名,如果没有找到,需要提示用户 for card_dict in card_list: if card_dict["name"] == find_name: print("姓名\u3000\t\t电话\u3000\t\tQQ \u3000\t\t邮箱") print("%s\u3000\t\t%s\u3000\t\t%s\u3000\t\t%s\u3000\t\t" % (card_dict["name"], card_dict["phone"], card_dict["qq"], card_dict["email"])) # 针对找到的字典信息进行修改和删除 deal_card(card_dict) break else: print("抱歉没有找到 %s" % find_name) # 修改和删除函数 def deal_card(find_dict): """处理查找到的名片 :param find_dict: 查找到的名片 """ print(find_dict) action_str = input("请选择要执行的操作 " "【1】 修改 " "【2】 删除 " "【0】 返回上级") if action_str == "1": find_dict["name"] = input_card_info(find_dict["name"], "姓名:") find_dict["phone"] = input_card_info(find_dict["phone"], "电话:") find_dict["qq"] = input_card_info(find_dict["qq"], "qq号码:") find_dict["email"] = input_card_info(find_dict["email"], "邮箱号码:") print("修改名片") elif action_str == "2": card_list.remove(find_dict) print("删除名片成功!") def input_card_info(dic_value, tip_message): """输入名片信息 :param dic_value:字典中原有的值 :param tip_message:输入的提示文字 :return:如果用户输入了内容,就返回内容,否则返回字典中原有的值 """ # 1.提示用户输入内容 result_str = input(tip_message) # 2.针对用户输入进行判断,如果用户输入了内容,直接返回结果 if len(result_str) > 0: return result_str # 3.如果用户没有输入内容,返回’字符串中原有的值‘ else: return dic_value 14.变量进阶(理解)
(1)变量的引用
1)引用的概念 在
2)变量引用的示例 在
3)函数的参数和返回值的传递 在 def test(num): print("-" * 50) print("%d 在函数内的内存地址是 %x" % (num, id(num))) result = 100 print("返回值 %d 在内存中的地址是 %x" % (result, id(result))) print("-" * 50) return result a = 10 print("调用函数前 内存地址是 %x" % id(a)) r = test(a) print("调用函数后 实参内存地址是 %x" % id(a)) print("调用函数后 返回值内存地址是 %x" % id(r)) (2)可变和不可变类型
a = 1 a = "hello" a = [1, 2, 3] a = [3, 2, 1] demo_list = [1, 2, 3] print("定义列表后的内存地址 %d" % id(demo_list)) demo_list.append(999) demo_list.pop(0) demo_list.remove(2) demo_list[0] = 10 print("修改数据后的内存地址 %d" % id(demo_list)) demo_dict = {"name": "小明"} print("定义字典后的内存地址 %d" % id(demo_dict)) demo_dict["age"] = 18 demo_dict.pop("name") demo_dict["name"] = "老王" print("修改数据后的内存地址 %d" % id(demo_dict))
注意
哈希
(3)局部变量和全局变量
1)局部变量
1.作用
def demo1(): num = 10 print(num) num = 20 print("修改后 %d" % num) def demo2(): num = 100 print(num) demo1() demo2() print("over") 10 修改后 20 100 over 2.生命周期
2)全局变量
# 定义一个全局变量 num = 10 def demo1(): print(num) def demo2(): print(num) demo1() demo2() print("over") 注意:函数执行时,需要处理变量时 会:
1.函数不能直接修改全局变量的引用
num = 10 def demo1(): print("demo1" + "-" * 50) # 只是定义了一个局部变量,不会修改到全局变量,只是变量名相同而已 num = 100 print(num) def demo2(): print("demo2" + "-" * 50) print(num) demo1() demo2() print("over") demo1-------------------------------------------------- 100 demo2-------------------------------------------------- 10 over
2.在函数内部修改全局变量的值
num = 10 def demo1(): print("demo1" + "-" * 50) # global 关键字,告诉 Python 解释器 num 是一个全局变量 global num # 只是定义了一个局部变量,不会修改到全局变量,只是变量名相同而已 num = 100 print(num) def demo2(): print("demo2" + "-" * 50) print(num) demo1() demo2() print("over") demo1-------------------------------------------------- 100 demo2-------------------------------------------------- 100 over 3.全局变量定义的位置
a = 10 def demo(): print("%d" % a) print("%d" % b) print("%d" % c) b = 20 demo() c = 30 Traceback (most recent call last): File "D:\桌面\Pythoncode\test.py", line 10, in <module> demo() File "D:\桌面\Pythoncode\test.py", line 7, in demo print("%d" % c) NameError: name 'c' is not defined 10 20 注意
4.全局变量命名的建议
15.函数进阶
(1)函数参数和返回值的作用函数根据 有没有参数 以及 有没有返回值,可以 相互组合,一共有 4 种 组合形式
1)无参数,无返回值 此类函数,不接收参数,也没有返回值,应用场景如下:
2)无参数,有返回值 此类函数,不接收参数,但是有返回值,应用场景如下:
3)有参数,无返回值 此类函数,接收参数,没有返回值,应用场景如下:
4)有参数,有返回值 此类函数,接收参数,同时有返回值,应用场景如下:
(2)函数的返回值
示例 —— 温度和湿度测量
def measure(): """返回当前的温度""" print("开始测量...") temp = 39 print("测量结束...") return temp result = measure() print(result) 开始测量... 测量结束... 39
def measure(): """返回当前的温度""" print("开始测量...") temp = 39 wetness = 10 print("测量结束...") # 如果函数返回的类型是元组,小括号可以省略 # return (temp, wetness) return temp, wetness # 如果函数返回的类型是元组,同时希望单独处理元组中的元素 # 可以使用多个变量,一次接收函数的返回结果 # 注意:使用多个变量接受结果时,变量的个数应该和元素中的个数保持一致 gl_temp, gl_wetness = measure() print(gl_temp) print(gl_wetness) 开始测量... 测量结束... 39 10
技巧
result = temp, wetness = measure() 面试题 —— 交换两个数字 题目要求
解法 1 —— 使用其他变量 # 解法 1 - 使用临时变量 c = b b = a a = c 解法 2 —— 不使用临时变量 # 解法 2 - 不使用临时变量 a = a + b b = a - b a = a - b 解法 3 —— Python 专有,利用元组 a, b = b, a (3)函数的参数 进阶1)不可变和可变的参数
def demo(num, num_list): print("函数内部") # 赋值语句 num = 200 num_list = [1, 2, 3] print(num) print(num_list) print("函数代码完成") gl_num = 99 gl_list = [4, 5, 6] demo(gl_num, gl_list) print(gl_num) print(gl_list) 函数内部 200 [1, 2, 3] 函数代码完成 99 [4, 5, 6]
def mutable(num_list): print("函数内部代码") num_list.append(9) print(num_list) print("函数执行完成") gl_list = [1, 2, 3] mutable(gl_list) print(gl_list) 函数内部代码 [1, 2, 3, 9] 函数执行完成 [1, 2, 3, 9] def mutable(num_list): # num_list = [1, 2, 3] num_list.extend([1, 2, 3]) print(num_list) gl_list = [6, 7, 8] mutable(gl_list) print(gl_list) [6, 7, 8, 1, 2, 3] [6, 7, 8, 1, 2, 3] 面试题 —— +=
def demo(num, num_list): print("函数内部代码") # num = num + num num += num # num_list.extend(num_list) 由于是调用方法,所以不会修改变量的引用 # 函数执行结束后,外部数据同样会发生变化 num_list += num_list print(num) print(num_list) print("函数代码完成") gl_num = 9 gl_list = [1, 2, 3] demo(gl_num, gl_list) print(gl_num) print(gl_list) 2)缺省参数
gl_num_list = [6, 3, 9] # 默认就是升序排序,因为这种应用需求更多 gl_num_list.sort() print(gl_num_list) # 只有当需要降序排序时,才需要传递 `reverse` 参数 gl_num_list.sort(reverse=True) print(gl_num_list) 指定函数的缺省参数
def print_info(name, gender=True): gender_text = "男生" if not gender: gender_text = "女生" print("%s 是 %s" % (name, gender_text)) 提示
缺省参数的注意事项: 1. 缺省参数的定义位置
def print_info(name, gender=True, title): 2.调用带有多个缺省参数的函数
def print_info(name, title="", gender=True): """ :param title: 职位 :param name: 班上同学的姓名 :param gender: True 男生 False 女生 """ gender_text = "男生" if not gender: gender_text = "女生" print("%s%s 是 %s" % (title, name, gender_text)) # 提示:在指定缺省参数的默认值时,应该使用最常见的值作为默认值! print_info("小明") print_info("老王", title="班长") print_info("小美", gender=False) 小明 是 男生 班长老王 是 男生 小美 是 女生 3)多值参数(知道) 1.定义支持多值参数的函数
def demo(num, *args, **kwargs): print(num) print(args) print(kwargs) demo(1, 2, 3, 4, 5, name="小明", age=18, gender=True) 1 (2, 3, 4, 5) {'name': '小明', 'age': 18, 'gender': True}
2.多值参数案例 —— 计算任意多个数字的和 需求
def sum_numbers(*args): num = 0 # 遍历 args 元组顺序求和 for n in args: num += n return num print(sum_numbers(1, 2, 3)) 3.元组和字典的拆包(知道)
如果不进行拆包: def demo(*args, **kwargs): print(args) print(kwargs) # 需要将一个元组变量/字典变量传递给函数对应的参数 gl_nums = (1, 2, 3) gl_xiaoming = {"name": "小明", "age": 18} # 会把 num_tuple 和 xiaoming 作为元组传递个 args # demo(gl_nums, gl_xiaoming) demo(gl_nums, gl_xiaoming) ((1, 2, 3), {'name': '小明', 'age': 18}) {} 进行拆包: def demo(*args, **kwargs): print(args) print(kwargs) # 需要将一个元组变量/字典变量传递给函数对应的参数 gl_nums = (1, 2, 3) gl_xiaoming = {"name": "小明", "age": 18} # 会把 num_tuple 和 xiaoming 作为元组传递个 args # demo(gl_nums, gl_xiaoming) demo(*gl_nums, **gl_xiaoming) (1, 2, 3) {'name': '小明', 'age': 18} (4)函数的递归
1)递归函数的特点 特点
代码特点
示例代码 def sum_numbers(num): print(num) # 递归的出口很重要,否则会出现死循环 if num == 1: return sum_numbers(num - 1) sum_numbers(3) 3 2 1 2)递归案例 —— 计算数字累加 需求
def sum_numbers(num): if num == 1: return 1 # 假设 sum_numbers 能够完成 num - 1 的累加 temp = sum_numbers(num - 1) # 函数内部的核心算法就是 两个数字的相加 return num + temp print(sum_numbers(100)) 5050
五.面向对象1.基本概念面向对象编程 ——
1)过程和函数(科普)
2)面相过程 和 面相对象 基本概念1.面相过程 —— 怎么做?
特点
2.面向对象 —— 谁来做?
特点
2.类和对象
(1)类和对象的概念类 和 对象 是 面向对象编程的 两个 核心概念 1.类
2.对象
(2)类和对象的关系
(3)类的设计在使用面相对象开发前,应该首先分析需求,确定一下,程序中需要包含哪些类! 在程序开发中,要设计一个类,通常需要满足一下三个要素:
大驼峰命名法
1.类名的确定 名词提炼法 分析 整个业务流程,出现的 名词,通常就是找到的类 2.属性和方法的确定
练习 1 需求
练习 2 需求
3.基础语法
(1)dir内置函数(知道)
在
提示
提示 利用好 (2)定义简单的类
1.定义只包含方法的类
class 类名: def 方法1(self, 参数列表): pass def 方法2(self, 参数列表): pass
2.创建对象
对象变量 = 类名() 3.第一个面向对象程序 需求
分析
class Cat: """这是一个猫类""" def eat(self): print("小猫爱吃鱼") def drink(self): print("小猫在喝水") tom = Cat() tom.drink() tom.eat() 小猫爱吃鱼 小猫要喝水 引用概念的强调
案例进阶 使用 Cat 类再创建一个对象 class Cat: def eat(self): print("小猫爱吃鱼") def drink(self): print("小猫要喝水") # 创建一个猫对象 tom = Cat() tom.eat() tom.drink() # 再创建一个猫对象 lazy_cat = Cat() lazy_cat.eat() lazy_cat.drink() print(tom) print(lazy_cat)
小猫爱吃鱼 小猫要喝水 小猫爱吃鱼 小猫要喝水 <__main__.Cat object at 0x0000015B34C77FD0> <__main__.Cat object at 0x0000015B34C77FA0> 通过结果可以观察出两个对象的内存地址不一样 故 (3)方法中的self参数1.案例改造 —给对象增加属性
class Cat: def eat(self): print("小猫爱吃鱼") def drink(self): print("小猫要喝水") # 创建一个猫对象 tom = Cat() tom.name = "Tom" tom.eat() tom.drink() # 再创建一个猫对象 lazy_cat = Cat() lazy_cat.name = "大懒猫" lazy_cat.eat() lazy_cat.drink() print(tom) print(lazy_cat) 2.使用self在方法内部输出每一只猫的名字
class Cat: def eat(self): print("%s 爱吃鱼" % self.name) tom = Cat() tom.name = "Tom" tom.eat() lazy_cat = Cat() lazy_cat.name = "大懒猫" lazy_cat.eat() Tom 爱吃鱼 大懒猫 爱吃鱼
(4)初始化方法1. 在类的外部给对象增加属性
class Cat: def eat(self): print("%s 爱吃鱼" % self.name) def drink(self): print("%s 爱吃鱼" % self.name) tom = Cat() tom.drink() tom.eat() tom.name = "Tom"
AttributeError: 'Cat' object has no attribute 'name' 属性错误:'Cat' 对象没有 'name' 属性 提示
2.初始化方法
在 class Cat: """这是一个猫类""" def __init__(self): print("初始化方法") 3.初始化方法内部定义属性
class Cat: def __init__(self): print("这是一个初始化方法") # 定义用 Cat 类创建的猫对象都有一个 name 的属性 self.name = "Tom" def eat(self): print("%s 爱吃鱼" % self.name) # 使用类名()创建对象的时候,会自动调用初始化方法 __init__ tom = Cat() tom.eat() 4.初始化的同时设置初始值
class Cat: def __init__(self, name): print("初始化方法 %s" % name) self.name = name def eat(self): print("%s 爱吃鱼" % self.name) tom = Cat("Tom") tom.eat() lazy_cat = Cat("大懒猫") lazy_cat.eat() 初始化方法 Tom Tom 爱吃鱼 初始化方法 大懒猫 大懒猫 爱吃鱼 (5)内置方法和属性
1.
class Cat: def __init__(self, new_name): self.name = new_name print("%s 来了" % self.name) def __del__(self): print("%s 去了" % self.name) # tom 是一个全局变量 tom = Cat("Tom") print(tom.name) # del 关键字可以删除一个对象 del tom print("-" * 50) Tom 来了 Tom Tom 去了 -------------------------------------------------- 2.
class Cat: def __init__(self, new_name): self.name = new_name print("%s 来了" % self.name) def __del__(self): print("%s 去了" % self.name) def __str__(self): return "我是小猫:%s" % self.name tom = Cat("Tom") print(tom) Tom 来了 我是小猫:Tom Tom 去了 (6)封装案例
1.封装
2.小明爱跑步 需求
class Person: def __init__(self, name, weight): self.name = name self.weight = weight def __str__(self): return "我的名字是 %s 体重是 %.2f公斤" % (self.name, self.weight) def run(self): print("%s 爱跑步,跑步锻炼身体" % self.name) self.weight -= 0.5 def eat(self): print("%s 爱吃零食,吃饱了再减肥" % self.name) self.weight += 1 xiaoming = Person("小明", 61.6) xiaoming.run() xiaoming.eat() xiaoming.eat() print(xiaoming.weight) 扩展 需求
提示
class Person: def __init__(self, name, weight): self.name = name self.weight = weight def __str__(self): return "我的名字是 %s 体重是 %.2f公斤" % (self.name, self.weight) def run(self): print("%s 爱跑步,跑步锻炼身体" % self.name) self.weight -= 0.5 def eat(self): print("%s 爱吃零食,吃饱了再减肥" % self.name) self.weight += 1 xiaoming = Person("小明", 75.0) xiaoming.run() xiaoming.eat() xiaoming.eat() print(xiaoming.weight) xiaomei = Person("小美", 45.0) xiaomei.run() xiaomei.eat() xiaomei.eat() print(xiaomei.weight) 3.摆放家具 需求
剩余面积
class HouseItem: def __init__(self, name, area): self.name = name self.area = area def __str__(self): return "【%s】,占用 %.2f 平方米" % (self.name, self.area) class House: def __init__(self, house_type, area): self.house_type = house_type self.area = area # 剩余面积 self.free_area = area # 家具名称列表 self.item_list = [] def __str__(self): return "户型:%s\n总面积:%.2f【剩余:%.2f】\n家具:%s" % (self.house_type, self.area, self.free_area, self.item_list) def add_item(self, item): print("要添加 %s" % item) # 1. 判断家具面积是否大于剩余面积 if item.area > self.free_area: print("%s 的面积太大,不能添加到房子中" % item.name) return # 2. 将家具的名称追加到名称列表中 self.item_list.append(item.name) # 3. 计算剩余面积 self.free_area -= item.area bed = HouseItem("席梦思", 4) cheat = HouseItem("衣柜", 2) table = HouseItem("餐桌", 1.5) print(bed) print(cheat) print(table) my_house = House("两室一厅", 60) my_house.add_item(bed) my_house.add_item(cheat) my_house.add_item(table) print(my_house) 小结
4.士兵突击 需求
4.私有属性和私有方法(1)应用场景
(2)定义方式
class Women: def __init__(self, name): self.name = name # 不要问女生的年龄 self.__age = 18 def __secret(self): # 在对象的方法内部是可以访问对象的私有属性的 print("我的年龄是 %d" % self.__age) xiaofang = Women("小芳") # 私有属性,外部不能直接访问 # print(xiaofang.__age) # 私有方法,外部不能直接调用 # xiaofang.__secret() (3)伪私有属性和私有方法
class Women: ? ? ?def __init__(self, name): ? ? ? ? ?self.name = name ? ? ? ?# 不要问女生的年龄 ? ? ? ?self.__age = 18 ? ? ?def __secret(self): ? ? ? ?# 在对象的方法内部是可以访问对象的私有属性的 ? ? ? ?print("我的年龄是 %d" % self.__age) ? ? xiaofang = Women("小芳") # 私有属性,外部不能直接访问到 print(xiaofang._Women__age) ? # 私有方法,外部不能直接调用 xiaofang._Women__secret() ? 18 我的年龄是 18 5.继承面向对象三大特性
(1)单继承1.概念、语法和特点 继承的概念:子类 拥有 父类 的所有 方法 和 属性 1) 继承的语法 class 类名(父类名): pass
2) 专业术语
3) 继承的传递性
子类 拥有 父类 以及 父类的父类 中封装的所有 属性 和 方法 提问 哮天犬 能够调用 答案 不能,因为 哮天犬 和 2.方法的重写
应用场景
重写 父类方法有两种情况:
1) 覆盖父类的方法
重写之后,在运行时,只会调用 子类中重写的方法,而不再会调用 父类封装的方法 2) 对父类方法进行 扩展
关于
调用父类方法的另外一种方式(知道)
父类名.方法(self)
提示
3.父类的 私有属性 和 私有方法
示例 class A: def __init__(self): self.num1 = 100 self.__num2 = 200 def __test(self): print("私有方法 %d %d" % (self.num1, self.__num2)) class B(A): def demo(self): # 1.访问父类的私有属性 # print("访问父类的私有属性 %d " % self.__num2) # 2.调用父类的私有方法 # self.__test() b = B() print(b)
class A: def __init__(self): self.num1 = 100 self.__num2 = 200 def __test(self): print("私有方法 %d %d" % (self.num1, self.__num2)) def test(self): print("公有方法") print("父类的公有方法 %d" % self.__num2) self.__test() class B(A): def demo(self): # 1.访问父类的私有属性 # print("访问父类的私有属性 %d " % self.__num2) # 2.调用父类的私有方法 # self.__test() # 3.访问父类的公有属性 print("公有属性:%d" % self.num1) # 4.调用父类的公有方法 self.test() b = B() print(b) # 在外界访问父类的公有属性/调用公有方法 b.test() print(b.num1) b.demo() a = A() a.test() (2)多继承概念
语法 class 子类名(父类名1, 父类名2...) pass class A: def test(self): print("test") class B: def demo(self): print("demo") class C(A, B): pass c = C() c.test() c.demo() test demo 1.注意事项
class A: def test(self): print("A-test") def demo(self): print("A-demo") class B: def test(self): print("B-test") def demo(self): print("B-demo") class C(A, B): pass c = C() c.test() c.demo() A-test A-demo 当调换顺序后: class C(A, B):-------> class A: def test(self): print("A-test") def demo(self): print("A-demo") class B: def test(self): print("B-test") def demo(self): print("B-demo") class C(B, A): pass c = C() c.test() c.demo() B-test B-demo 对于上述情况基于Python中的MRO Python 中的 MRO —— 方法搜索顺序(知道)
print(C.__mro__) 输出结果 (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
2.新式类与旧式(经典)类
为了保证编写的代码能够同时在 class 类名(object): pass 6.多态多态 不同的对象调用相同的方法,产生不同的执行结果,增加代码的灵活度
(1)案例演练class Dog(object): def __init__(self, name): self.name = name def game(self): print("%s 蹦蹦跳跳的玩耍..." % self.name) class XiaoTianDog(Dog): def game(self): print("%s飞到天上去玩耍..." % self.name) class Person(object): def __init__(self, name): self.name = name def game_with_dog(self, dog): print("%s 和 %s 快乐的玩耍..." % (self.name, dog.name)) # 让狗玩耍 dog.game() # 1.创建一个狗对象 # wangcai = Dog("旺财") wangcai = XiaoTianDog("飞天旺财") # 2.创建一个小明对象 xiaoming = Person("小明") # 3.让小明调用和狗玩的方法 xiaoming.game_with_dog(wangcai) (2)类的结构1.术语-实例
因此,也通常会把:
在程序执行时:
结论: 每一个对象都拥有自己独立的内存空间,保存各自不同的属性 多个对象的方法,在内存中只有一份,在调用方法时,需要把对象的引用传递到方法内部 2.类是特殊的对象 (3)类属性和实例属性概念和使用: class Tool(object): # 使用赋值语句定义类属性,记录所有工具对象的数量 count = 0 def __init__(self, name): self.name = name # 让类属性的值+1 Tool.count += 1 # 1.创建工具对象 tool1 = Tool("斧头") tool2 = Tool("榔头") tool3 = Tool("水桶") # 2.输出工具对象的总数 print(Tool.count) 3 属性获取机制: (4)类方法和静态方法1.类方法 实例需求: @classmethod def show_tool_count(cls): """显示工具对象的总数""" print("工具对象的总数 %d " % cls.count) class Tool(object): # 使用赋值语句定义类属性,记录所有工具对象的数量 count = 0 @classmethod def show_tool_count(cls): print("工具对象的数量 %d " % cls.count) def __init__(self, name): self.name = name # 让类属性的值+1 Tool.count += 1 # 创建工具对象 tool1 = Tool("斧头") tool2 = Tool("榔头") # 调用类方法 Tool.show_tool_count() 2.静态方法 class Dog(object): @staticmethod def run(): # 不访问实例属性/类属性 print("小狗要跑...") # 通过类名,调用静态方法 - 不需要创建对象 Dog.run() 小狗要跑... (5)方法综合案例class Game(object): # 历史最高分 top_score = 0 def __init__(self, player_name): self.player_name = player_name @staticmethod def show_help(): print("帮助信息:让僵尸进入大门") @classmethod def show_top_score(cls): print("历史记录 %d " % cls.top_score) def start_game(self): print("%s 开始游戏啦..." % self.player_name) # 1.查看游戏的帮助信息 Game.show_help() # 2.查看历史最高分 Game.show_top_score() # 3.创建游戏对象 player = Game("小明") player.start_game() 六.单例1.单例设计模式
单例设计模式的应用场景:
2.
|
序号 | 函数/方法 | 说明 |
---|---|---|
01 | open | 打开文件,并且返回文件操作对象 |
02 | read | 将文件内容读取到内存 |
03 | write | 将指定内容写入文件 |
04 | close | 关闭文件 |
open
函数负责打开文件,并且返回文件对象
read
/write
/close
三个方法都需要通过 文件对象 来调用
open
函数的第一个参数是要打开的文件名(文件名区分大小写)
如果文件 存在,返回 文件操作对象
如果文件 不存在,会 抛出异常
read
方法可以一次性 读入 并 返回 文件的 所有内容
close
方法负责 关闭文件
如果 忘记关闭文件,会造成系统资源消耗,而且会影响到后续对文件的访问
注意:read
方法执行后,会把 文件指针 移动到 文件的末尾
# 1. 打开 - 文件名需要注意大小写 file = open("README.txt") # 2. 读取 text = file.read() print(text) # 3. 关闭 file.close()
提示
在开发中,通常会先编写 打开 和 关闭 的代码,再编写中间针对文件的 读/写 操作!
文件指针(知道)
文件指针 标记 从哪个位置开始读取数据
第一次打开 文件时,通常 文件指针会指向文件的开始位置
当执行了 read
方法后,文件指针 会移动到 读取内容的末尾
默认情况下会移动到 文件末尾
思考
如果执行了一次 read
方法,读取了所有内容,那么再次调用 read
方法,还能够获得到内容吗?
答案
不能
第一次读取之后,文件指针移动到了文件末尾,再次调用不会读取到任何的内容
# 1. 打开 - 文件名需要注意大小写 file = open("README.txt") # 2. 读取 text = file.read() print(text) print("-"*50) text = file.read() print(text) # 3. 关闭 file.close()
hello world --------------------------------------------------
open
函数默认以 只读方式 打开文件,并且返回文件对象
语法如下:
f = open("文件名", "访问方式")
访问方式 | 说明 |
---|---|
r | 以只读方式打开文件。文件的指针将会放在文件的开头,这是默认模式。如果文件不存在,抛出异常 |
w | 以只写方式打开文件。如果文件存在会被覆盖。如果文件不存在,创建新文件 |
a | 以追加方式打开文件。如果该文件已存在,文件指针将会放在文件的结尾。如果文件不存在,创建新文件进行写入 |
r+ | 以读写方式打开文件。文件的指针将会放在文件的开头。如果文件不存在,抛出异常 |
w+ | 以读写方式打开文件。如果文件存在会被覆盖。如果文件不存在,创建新文件 |
a+ | 以读写方式打开文件。如果该文件已存在,文件指针将会放在文件的结尾。如果文件不存在,创建新文件进行写入 |
提示
频繁的移动文件指针,会影响文件的读写效率,开发中更多的时候会以 只读、只写 的方式来操作文件
写入文件示例
# 打开文件 f = open("README.txt", "w") f.write("hello python!\n") f.write("今天天气真好\n") # 关闭文件 f.close()
read
方法默认会把文件的 所有内容 一次性读取到内存
如果文件太大,对内存的占用会非常严重
readline
方法
readline
方法可以一次读取一行内容
方法执行后,会把 文件指针 移动到下一行,准备再次读取
读取大文件的正确姿势
# 打开文件 file = open("README.txt") while True: # 读取一行内容 text = file.readline() # 判断是否读到内容 if not text: break # 每读取一行的末尾已经有了一个 `\n` print(text, end="") # 关闭文件 file.close()
文件读写案例 ——
小文件复制
用代码的方式,来实现文件复制过程
打开一个已有文件,读取完整内容,并写入到另外一个文件
# 1. 打开文件 file_read = open("README") file_write = open("README[复件]", "w") # 2. 读取并写入文件 text = file_read.read() file_write.write(text) # 3. 关闭文件 file_read.close() file_write.close()
大文件复制
打开一个已有文件,逐行读取内容,并顺序写入到另外一个文件
# 1. 打开文件 file_read = open("README") file_write = open("README[复件]", "w") # 2. 读取并写入文件 while True: # 每次读取一行 text = file_read.readline() # 判断是否读取到内容 if not text: break file_write.write(text) # 3. 关闭文件 file_read.close() file_write.close()
在 终端 / 文件浏览器、 中可以执行常规的 文件 / 目录 管理操作,例如:
创建、重命名、删除、改变路径、查看目录内容、……
在 Python
中,如果希望通过程序实现上述功能,需要导入 os
模块
序号 | 方法名 | 说明 | 示例 |
---|---|---|---|
01 | rename | 重命名文件 | os.rename(源文件名, 目标文件名) |
02 | remove | 删除文件 | os.remove(文件名) |
序号 | 方法名 | 说明 | 示例 |
---|---|---|---|
01 | listdir | 目录列表 | os.listdir(目录名) |
02 | mkdir | 创建目录 | os.mkdir(目录名) |
03 | rmdir | 删除目录 | os.rmdir(目录名) |
04 | getcwd | 获取当前目录 | os.getcwd() |
05 | chdir | 修改工作目录 | os.chdir(目标目录) |
06 | path.isdir | 判断是否是文件 | os.path.isdir(文件路径) |
提示:文件或者目录操作都支持 相对路径 和 绝对路径
文本文件存储的内容是基于 字符编码 的文件,常见的编码有 ASCII
编码,UNICODE
编码等
Python 2.x 默认使用
ASCII
编码格式 Python 3.x 默认使用UTF-8
编码格式
ASCII
编码
计算机中只有 256
个 ASCII
字符
一个 ASCII
在内存中占用 1 个字节 的空间
8
个 0/1
的排列组合方式一共有 256
种,也就是 2 ** 8
UTF-8
编码格式
计算机中使用 1~6 个字节 来表示一个 UTF-8
字符,涵盖了 地球上几乎所有地区的文字
大多数汉字会使用 3 个字节 表示
UTF-8
是 UNICODE
编码的一种编码格式
Python 2.x 默认使用
ASCII
编码格式 Python 3.x 默认使用UTF-8
编码格式
在 Python 2.x 文件的 第一行 增加以下代码,解释器会以 utf-8
编码来处理 python 文件
# *-* coding:utf8 *-*
这方式是官方推荐使用的!
也可以使用
# coding=utf8
unicode 字符串
在 Python 2.x
中,即使指定了文件使用 UTF-8
的编码格式,但是在遍历字符串时,仍然会 以字节为单位遍历 字符串
要能够 正确的遍历字符串,在定义字符串时,需要 在字符串的引号前,增加一个小写字母 u
,告诉解释器这是一个 unicode
字符串(使用 UTF-8
编码格式的字符串)
# *-* coding:utf8 *-* ? # 在字符串前,增加一个 `u` 表示这个字符串是一个 utf8 字符串 hello_str = u"你好世界" ? print(hello_str) ? for c in hello_str: ? ?print(c) ?
eval()
函数十分强大 —— 将字符串 当成 有效的表达式 来求值 并 返回计算结果
# 基本的数学计算 In [1]: eval("1 + 1") Out[1]: 2 # 字符串重复 In [2]: eval("'*' * 10") Out[2]: '**********' # 将字符串转换成列表 In [3]: type(eval("[1, 2, 3, 4, 5]")) Out[3]: list # 将字符串转换成字典 In [4]: type(eval("{'name': 'xiaoming', 'age': 18}")) Out[4]: dict
需求
提示用户输入一个 加减乘除混合运算
返回计算结果
input_str = input("请输入一个算术题:") print(eval(input_str))
请输入一个算术题:5*5 25
eval
在开发时千万不要使用
eval
直接转换input
的结果
__import__('os').system('ls')
等价代码
import os os.system("终端命令")
执行成功,返回 0
执行失败,返回错误信息
在Windows系统中在cmd中输入:pip install pygame 即可安装
win 输入 python -m pygame.examples.aliens 如果进入:
表示安装成功
提示:
pygame.Rect是一个比较特殊的类,内部只是封装了一些数字技术
不执行pygame.init()方法同样是能够直接使用
eg:
import pygame hero_rect = pygame.Rect(100, 500, 120, 125) print("英雄的原点 %d %d " % (hero_rect.x, hero_rect.y)) print("英雄的尺寸 %d %d " % (hero_rect.width, hero_rect.height)) print("%d %d " % hero_rect.size)
英雄的原点 100 500 英雄的尺寸 120 125 120 125
pygame专门提供了一个模块pygame.display
用于创建管理主窗口
eg:
import pygame pygame.init() # 创建游戏窗口 480*700 screen = pygame.display.set_mode((480, 700)) # 游戏循环 while True: pass pygame.quit()
import pygame pygame.init() # 创建游戏窗口 480*700 screen = pygame.display.set_mode((480, 700)) # 绘制背景图像 # 1> 加载图像数据 bg = pygame.image.load("./images/background.png") # 2> blit 绘制图像(这里的(0,0)的意思是在屏幕的左上角绘制图像) screen.blit(bg, (0, 0)) # 3> 更新屏幕的显示 pygame.display.update() # 游戏循环 while True: pass pygame.quit()
import pygame pygame.init() # 创建游戏窗口 480*700 screen = pygame.display.set_mode((480, 700)) # 绘制背景图像 # 1> 加载图像数据 bg = pygame.image.load("./images/background.png") # 2> blit 绘制图像(这里的(0,0)的意思是在屏幕的左上角绘制图像) screen.blit(bg, (0, 0)) # 3> 更新屏幕的显示 pygame.display.update() # 绘制英雄的飞机 hero = pygame.image.load("./images/me1.png") screen.blit(hero, (200, 600)) pygame.display.update() # 游戏循环 while True: pass pygame.quit()
现在的飞机已经被绘制到屏幕上了,怎么能让飞机移动呢?
跟电影的原理类似,游戏中的动画效果,本质上是快速的在屏幕上绘制图像。电影是将多张静止的电影胶片连续、快速的播放,产生连贯的视觉效果!
一般在电脑上每秒绘制60次,就能够达到非常连续高品质的动画效果。每次绘制的结果被称为帧Frame
游戏循环的作用
保证游戏不会直接退出
变化图像位置--动画效果
每隔1/60秒 移动一下所有图像的位置
调用pygame.display.update()更新屏幕显示
检测用户交互--按键、鼠标等...
pygame
专门提供了一个类pygane.tine.Clock
可以非常方便的设置屏幕绘制速度--刷新帧率
要使用时钟对象 需要两步:
在游戏初始化创建一个时钟对象
在游戏循环中让时钟对象调用 tick(帧率)方法
tick
方法会根据上次被调用的时间,自动设置游戏循环中的延时
eg:
import pygame pygame.init() # 创建游戏窗口 480*700 screen = pygame.display.set_mode((480, 700)) # 绘制背景图像 # 1> 加载图像数据 bg = pygame.image.load("./images/background.png") # 2> blit 绘制图像(这里的(0,0)的意思是在屏幕的左上角绘制图像) screen.blit(bg, (0, 0)) # 3> 更新屏幕的显示 pygame.display.update() # 绘制英雄的飞机 hero = pygame.image.load("./images/me1.png") screen.blit(hero, (200, 600)) pygame.display.update() # 创建时钟对象 clock = pygame.time.Clock() # 游戏循环 i = 0 while True: clock.tick(60) print(i) i = i + 1 pass pygame.quit()
若把时钟对象中的60改成1
则:
import pygame ? pygame.init() ? # 创建游戏窗口 480*700 screen = pygame.display.set_mode((480, 700)) ? # 绘制背景图像 # 1> 加载图像数据 bg = pygame.image.load("./images/background.png") # 2> blit 绘制图像(这里的(0,0)的意思是在屏幕的左上角绘制图像) screen.blit(bg, (0, 0)) # 3> 更新屏幕的显示 pygame.display.update() ? # 绘制英雄的飞机 hero = pygame.image.load("./images/me1.png") screen.blit(hero, (200, 600)) pygame.display.update() ? ? # 创建时钟对象 clock = pygame.time.Clock() # 游戏循环 i = 0 ? ? while True: ? ?clock.tick(1) ? ?print(i) ? ?i = i + 1 ? ? ?pass ? pygame.quit()
(4)英雄的简单动画实现
需求:
在游戏初始化定义一个 pygame.Rect
的变量记录英雄的初始位置
在游戏循环中每次让英雄的y-1
-- 向上移动
y <= 0
将英雄移动到屏幕的底部
提示:
每一次调用 update()方法之前,需要把所有的游戏图像都重新绘制一遍
而且应该 最先 重新绘制 背景图像
import pygame pygame.init() # 创建游戏窗口 480*700 screen = pygame.display.set_mode((480, 700)) # 绘制背景图像 # 1> 加载图像数据 bg = pygame.image.load("./images/background.png") # 2> blit 绘制图像(这里的(0,0)的意思是在屏幕的左上角绘制图像) screen.blit(bg, (0, 0)) # 3> 更新屏幕的显示 pygame.display.update() # 绘制英雄的飞机 hero = pygame.image.load("./images/me1.png") screen.blit(hero, (150, 300)) pygame.display.update() # 创建时钟对象 clock = pygame.time.Clock() # 1. 定义rect记录飞机的初始位置 hero_rect = pygame.Rect(150, 300, 102, 126) # 游戏循环 while True: # 可以指定循环体内部的代码执行的频率 clock.tick(60) # 2. 修改飞机的位置 hero_rect.y -= 1 # 判断飞机的位置如果到了边界再次回到底部 if hero_rect.y <= 0: hero_rect.y = 700 # 3. 调用blit方法绘制图像 # 再次绘制背景图像,以防止留下残影 screen.blit(bg, (0, 0)) screen.blit(hero, hero_rect) # 4. 调用update方法更新显示 pygame.display.update() pass pygame.quit()
事件 event
就是游戏启动后,用户针对游戏所做的操作
例如:点击关闭按钮,点击鼠标,按下键盘...
监听
在游戏循环中,判断用户 具体的操作
只有捕获到用户具体的操作,才能有针对性的做出响应
代码实现
pygame
中通过pygame.event.get()
可以获得用户当前所做动作的事件列表。用户可以同一时间做很多事情
提示:这段代码非常的固定,几乎所有的pygame
游戏都大同小异!
import pygame ? pygame.init() ? # 创建游戏窗口 480*700 screen = pygame.display.set_mode((480, 700)) ? # 绘制背景图像 # 1> 加载图像数据 bg = pygame.image.load("./images/background.png") # 2> blit 绘制图像(这里的(0,0)的意思是在屏幕的左上角绘制图像) screen.blit(bg, (0, 0)) # 3> 更新屏幕的显示 pygame.display.update() ? # 绘制英雄的飞机 hero = pygame.image.load("./images/me1.png") screen.blit(hero, (150, 300)) pygame.display.update() ? ? # 创建时钟对象 clock = pygame.time.Clock() ? # 1. 定义rect记录飞机的初始位置 hero_rect = pygame.Rect(150, 300, 102, 126) ? # 游戏循环 while True: ? ?# 可以指定循环体内部的代码执行的频率 ? ?clock.tick(120) ? ? ?# 事件监听(检测是否通过鼠标关闭) ? ?for event in pygame.event.get(): ? ? ? ?if event.type == pygame.QUIT: ? ? ? ? ? ?print("游戏退出...") ? ? ? ? ? ?# 先卸载quit所有模块,再退出 ? ? ? ? ? ?pygame.quit() ? ? ? ? ? ?exit() ? ? ?# 捕获事件 ? ?event_list = pygame.event.get() ? ?if len(event_list) > 0: ? ? ? ?print(event_list) ? ? ? ?# 2. 修改飞机的位置 ? ?hero_rect.y -= 1 ? ? ? ?# 判断飞机的位置如果到了边界再次回到底部 ? ?if hero_rect.y <= -126: ? ? ? ?hero_rect.y = 700 ? ? ?# 3. 调用blit方法绘制图像 ? ?# 再次绘制背景图像,以防止留下残影 ? ?screen.blit(bg, (0, 0)) ? ?screen.blit(hero, hero_rect) ? ? ?# 4. 调用update方法更新显示 ? ?pygame.display.update() ? ? ?pass ? pygame.quit() ? ?
随着鼠标在框体的移动,控制台也会输出对应的信息,点击右上角的关闭按钮游戏也会随之关闭
import pygame class GameSprite(pygame.sprite.Sprite): """飞机大战精灵""" # 在开发子类时,如果子类的父类不是object的基类,在初始化方法中需要主动调用父类的初始化方法 # 若不主动调用父类的初始化方法,就没有办法享受到父类中已经封装好的初始化方法 def __init__(self, image_name, speed=1): # 调用父类的初始化方法 super.__init__() # 定义对象 self.image = pygame.image.load(image_name) self.rect = self.image.get_rect() self.speed = speed def update(self): # 在屏幕的垂直方向移动 self.rect.y += self.speed
import pygame from plane_sprites import * ? # 游戏的初始化 pygame.init() ? # 创建游戏窗口 480*700 screen = pygame.display.set_mode((480, 700)) ? # 绘制背景图像 # 1> 加载图像数据 bg = pygame.image.load("./images/background.png") # 2> blit 绘制图像(这里的(0,0)的意思是在屏幕的左上角绘制图像) screen.blit(bg, (0, 0)) # 3> 更新屏幕的显示 pygame.display.update() ? # 绘制英雄的飞机 hero = pygame.image.load("./images/me1.png") screen.blit(hero, (150, 300)) pygame.display.update() ? ? # 创建时钟对象 clock = pygame.time.Clock() ? # 1. 定义rect记录飞机的初始位置 hero_rect = pygame.Rect(150, 300, 102, 126) ? # 创建敌机的精灵 enemy = GameSprite("./images/enemy1.png") enemy1 = GameSprite("./images/enemy1.png",2) # 创建敌机的精灵族 enemy_group = pygame.sprite.Group(enemy, enemy1) ? ? ? ? # 游戏循环 while True: ? ?# 可以指定循环体内部的代码执行的频率 ? ?clock.tick(120) ? ? ?# 事件监听(检测是否通过鼠标关闭) ? ?for event in pygame.event.get(): ? ? ? ?if event.type == pygame.QUIT: ? ? ? ? ? ?print("游戏退出...") ? ? ? ? ? ?# 先卸载quit所有模块,再退出 ? ? ? ? ? ?pygame.quit() ? ? ? ? ? ?exit() ? ? ?# 捕获事件 ? ?event_list = pygame.event.get() ? ?if len(event_list) > 0: ? ? ? ?print(event_list) ? ? ? ?# 2. 修改飞机的位置 ? ?hero_rect.y -= 1 ? ? ? ?# 判断飞机的位置如果到了边界再次回到底部 ? ?if hero_rect.y <= -126: ? ? ? ?hero_rect.y = 700 ? ? ?# 3. 调用blit方法绘制图像 ? ?# 再次绘制背景图像,以防止留下残影 ? ?screen.blit(bg, (0, 0)) ? ?screen.blit(hero, hero_rect) ? ? ?# 让精灵组调用两个方法 ? ?# update - 让组中的所有精灵更新位置 ? ?enemy_group.update() ? ? ? ?# draw - 在screen上绘制所有的精灵 ? ?enemy_group.draw(screen) ? ? ?# 4. 调用update方法更新显示 ? ?pygame.display.update() ? ? ?pass ? pygame.quit() ?
目标 —— 使用 面相对象 设计 飞机大战游戏类
回顾 快速入门案例,一个游戏主程序的 职责 可以分为两个部分:
游戏初始化
游戏循环
根据明确的职责,设计 PlaneGame
类如下:
提示 根据 职责 封装私有方法,可以避免某一个方法的代码写得太过冗长
如果某一个方法编写的太长,既不好阅读,也不好维护!
游戏初始化 —— __init__()
会调用以下方法:
方法 | 职责 |
---|---|
__create_sprites(self) | 创建所有精灵和精灵组 |
游戏循环 —— start_game()
会调用以下方法:
方法 | 职责 |
---|---|
__event_handler(self) | 事件监听 |
__check_collide(self) | 碰撞检测 —— 子弹销毁敌机、敌机撞毁英雄 |
__update_sprites(self) | 精灵组更新和绘制 |
__game_over() | 游戏结束 |
plane_main
封装 主游戏类
创建 游戏对象
启动游戏
plane_sprites
封装游戏中 所有 需要使用的 精灵子类
提供游戏的 相关工具
代码实现
新建 plane_main.py
文件,并且设置为可执行
编写 基础代码
import pygame from plane_sprites import * class PlaneGame(object): """飞机大战主游戏""" def __init__(self): print("游戏初始化") def start_game(self): print("开始游戏...") if __name__ == '__main__': # 创建游戏对象 game = PlaneGame() # 开始游戏 game.start_game()
完成 __init__()
代码如下:
def __init__(self): print("游戏初始化") # 1. 创建游戏的窗口 self.screen = pygame.display.set_mode((480, 700)) # 2. 创建游戏的时钟 self.clock = pygame.time.Clock() # 3. 调用私有方法,精灵和精灵组的创建 self.__create_sprites() def __create_sprites(self): pass
使用 常量 代替固定的数值
常量 —— 不变化的量
变量 —— 可以变化的量
应用场景
在开发时,可能会需要使用 固定的数值,例如 屏幕的高度 是 700
这个时候,建议 不要 直接使用固定数值,而应该使用 常量
在开发时,为了保证代码的可维护性,尽量不要使用 魔法数字
常量的定义
定义 常量 和 定义 变量 的语法完全一样,都是使用 赋值语句
常量 的 命名 应该 所有字母都使用大写,单词与单词之间使用下划线连接
常量的好处
阅读代码时,通过 常量名 见名之意,不需要猜测数字的含义
如果需要 调整值,只需要 修改常量定义 就可以实现 统一修改
提示:Python 中并没有真正意义的常量,只是通过命名的约定 —— 所有字母都是大写的就是常量,开发时不要轻易的修改!
代码调整
在 plane_sprites.py
中增加常量定义
import pygame # 游戏屏幕大小 SCREEN_RECT = pygame.Rect(0, 0, 480, 700)
修改 plane_main.py
中的窗口大小
self.screen = pygame.display.set_mode(SCREEN_RECT.size)
完成 start_game()
基础代码如下:
def start_game(self): """开始游戏""" print("开始游戏...") while True: # 1. 设置刷新帧率 self.clock.tick(60) # 2. 事件监听 self.__event_handler() # 3. 碰撞检测 self.__check_collide() # 4. 更新精灵组 self.__update_sprites() # 5. 更新屏幕显示 pygame.display.update() def __event_handler(self): """事件监听""" for event in pygame.event.get(): if event.type == pygame.QUIT: PlaneGame.__game_over() def __check_collide(self): """碰撞检测""" pass def __update_sprites(self): """更新精灵组""" pass @staticmethod def __game_over(): """游戏结束""" print("游戏结束") pygame.quit() exit()
创建精灵组方法
def __create_sprites(self): """创建精灵组""" # 背景组 self.back_group = pygame.sprite.Group() # 敌机组 self.enemy_group = pygame.sprite.Group() # 英雄组 self.hero_group = pygame.sprite.Group()
更新精灵组方法
def __update_sprites(self): """更新精灵组""" for group in [self.back_group, self.enemy_group, self.hero_group]: group.update() group.draw(self.screen)
背景交替滚动的思路确定
显示游戏背景
运行 备课代码,观察 背景图像的显示效果:
游戏启动后,背景图像 会 连续不断地 向下方 移动
在 视觉上 产生英雄的飞机不断向上方飞行的 错觉 —— 在很多跑酷类游戏中常用的套路
游戏的背景 不断变化
游戏的主角 位置保持不变
解决办法
创建两张背景图像精灵
第 1
张 完全和屏幕重合
第 2
张在 屏幕的正上方
两张图像 一起向下方运动
self.rect.y += self.speed
当 任意背景精灵 的 rect.y >= 屏幕的高度
说明已经 移动到屏幕下方
将 移动到屏幕下方的这张图像 设置到 屏幕的正上方
rect.y = -rect.height
初始化方法
直接指定 背景图片
is_alt
判断是否是另一张图像
False
表示 第一张图像,需要与屏幕重合
True
表示 另一张图像,在屏幕的正上方
update() 方法
判断 是否移动出屏幕,如果是,将图像设置到 屏幕的正上方,从而实现 交替滚动
继承 如果父类提供的方法,不能满足子类的需求:
派生一个子类
在子类中针对特有的需求,重写父类方法,并且进行扩展
在 plane_sprites
新建 Background
继承自 GameSprite
class Background(GameSprite): """游戏背景精灵""" def update(self): # 1. 调用父类的方法实现 super().update() # 2. 判断是否移出屏幕,如果移出屏幕,将图像设置到屏幕的上方 if self.rect.y >= SCREEN_RECT.height: self.rect.y = -self.rect.height
plane_main.py
中显示背景精灵在 __create_sprites
方法中创建 精灵 和 精灵组
在 __update_sprites
方法中,让 精灵组 调用 update()
和 draw()
方法
__create_sprites
方法
def __create_sprites(self): # 创建背景精灵和精灵组 bg1 = Background("./images/background.png") bg2 = Background("./images/background.png") bg2.rect.y = -bg2.rect.height self.back_group = pygame.sprite.Group(bg1, bg2)
__update_sprites
方法
def __update_sprites(self): self.back_group.update() self.back_group.draw(self.screen)
思考 —— 上一小结完成的代码存在什么样的问题?能否简化?
在主程序中,创建的两个背景精灵,传入了相同的图像文件路径
创建 第二个 背景精灵 时,在主程序中,设置背景精灵的图像位置
思考 —— 精灵 初始位置 的设置,应该 由主程序负责?还是 由精灵自己负责?
答案 —— 由精灵自己负责
根据面向对象设计原则,应该将对象的职责,封装到类的代码内部
尽量简化程序调用一方的代码调用
初始化方法
直接指定 背景图片
is_alt
判断是否是另一张图像
False
表示 第一张图像,需要与屏幕重合
True
表示 另一张图像,在屏幕的正上方
在 plane_sprites.py
中实现 Background
的 初始化方法
def __init__(self, is_alt=False): image_name = "./images/background.png" super().__init__(image_name) # 判断是否交替图片,如果是,将图片设置到屏幕顶部 if is_alt: self.rect.y = -self.rect.height
修改 plane_main
的 __create_sprites
方法
# 创建背景精灵和精灵组 bg1 = Background() bg2 = Background(True) self.back_group = pygame.sprite.Group(bg1, bg2)
"""输入1000以内的素数及其这些素数的和""" n = 1000 s = 0 print("1000以内的素数为:", end='') while n >= 3: for i in range(2, int(n ** 0.5 + 1)): if n % i == 0: break else: print(n, end=' ') s = n + s n = n - 1 print("\n1000以内的素数的和为:%d" % (s + 2))
def factors(n): iffactor = False print("该数除了1和自身以外的因子为:") for i in range(2, int(n // 2) + 1): if n % i == 0: print(i, end=' ') iffactor = True if not iffactor: print("无") num = input("请从键盘输入一个数:") factors(int(num))
class Vehicle(object): def __init__(self, wheels, weight): self.setWheels(wheels) self.setWeight(weight) def setWheels(self, wheels): self.whells = wheels def setWeight(self, weight): self.weight = weight def getWhells(self): return self.whells def getWeight(self): return self.weight def display(self): print("汽车车轮个数为:%s,汽车的重量为%s 吨" % (self.whells, self.weight)) class Car(Vehicle): def __init__(self, wheels, weight, passenger_load='4'): super(Car, self).__init__(wheels, weight) self.passenger_load = passenger_load def display(self): super(Car, self).display() print("该汽车为小汽车,载客为:%s" % self.passenger_load) class Truk(Vehicle): def __init__(self, wheels, weight, passenger_load, load): super(Truk, self).__init__(wheels, weight) self.passenger_load = passenger_load self.load = load def display(self): super(Truk, self).display() print("该汽车为货车,载客为:%s,载重为:%s 吨" % (self.passenger_load, self.load)) if __name__ == '__main__': car_passenger_load = input("请输入小汽车的载客数量:") truk_passenger_load = input("请输入货车的载客数量:") truk_load = input("请输入货车的载重量:") car = Car(4, 2, car_passenger_load) car.display() truk = Truk(4, 10, truk_load, truk_passenger_load) truk.display()
class Person(object): # Person类 def __init__(self, number, name): self.set_number(number) self.set_name(name) def set_number(self, number): self.number = number def set_name(self, name): self.name = name def get_number(self): return self.number def get_name(self): return self.name def print_number_name(self): print("编号为:%s,姓名为:%s" % (self.get_number(), self.get_name()), end=",") class Student(Person): def __init__(self, number, name, classnumber, grade): super(Student, self).__init__(number, name) Person.__init__(self, number, name) self.set_classnumber(classnumber) self.set_grade(grade) # 设置Student类中的set和get方法 def set_classnumber(self, classnumber): self.classnumber = classnumber def set_grade(self, grade): self.grade = grade def get_classnumber(self): return self.classnumber def get_grade(self): return self.grade def print_classnumber_grade(self): print("学生", end="--->") # 调用Person类中的输出编号和姓名的方法 super(Student, self).print_number_name() print("班号:%s,成绩:%s" % (self.get_classnumber(), self.get_grade())) class Teacher(Person): def __init__(self, number, name, title, department): super(Teacher, self).__init__(number, name) Person.__init__(self, number, name) self.set_title(title) self.set_department(department) # 设置Teacher类中的set和get方法 def set_title(self, title): self.title = title def set_department(self, department): self.department = department def get_title(self): return self.title def get_department(self): return self.department # 调用Person类中的输出编号和姓名的方法 def print_title_department(self): print("老师", end="--->") super(Teacher, self).print_number_name() print("称号:%s,部门:%s" % (self.get_title(), self.get_department())) if __name__ == '__main__': # 使用户输入学生和老师的信息 list1 = input("请输入学生的编号,姓名,班号,成绩(用空格分隔):") list2 = input("请输入老师的编号,姓名,班号,成绩(用空格分隔):") # 把用户输入的字符串类型的信息通过map()方法和split()方法转化为列表 list_student = list(map(str, list1.split(' '))) list_teacher = list(map(str, list2.split(' '))) student = Student(list_student[0], list_student[1], list_student[2], list_student[3]) teacher = Teacher(list_teacher[0], list_teacher[1], list_teacher[2], list_teacher[3]) # 分别调用两个类中的输出信息方法 student.print_classnumber_grade() teacher.print_title_department()
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 | -2024/12/24 11:28:19- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |
数据统计 |