计算机不能直接理解任何除机器语言以外的语言,所以必须要把程序员所写的程序语言翻译成机器语言,计算机才能执行程序。将其他语言翻译成机器语言的工具,被称为编译器。
编译器翻译的方式有两种:一个是编译,另外一个是解释。两种方式之间的区别在于翻译时间点的不同。当编译器以解释方式运行的时候,也称之为解释器。
编译型语言:程序在执行之前需要一个专门的编译过程,把程序编译成为机器语言的文件,运行时不需要重新翻译,直接使用编译的结果就行了。程序执行效率高,依赖编译器,跨平台性差些。如 C、C++。
解释型语言:解释型语言编写的程序不进行预先编译,以文本方式存储程序代码,会将代码一句一句直接运行。在发布程序时,看起来省了道编译工序,但是在运行程序的时候,必须先解释再运行。
编译型语言和解释型语言对比
这些想法中的基本都已经成为现实,Python 已经成为一门流行的编程语言
Python 开发者的哲学是:用一种方法,最好是只有一种方法来做一件事。
如果面临多种选择,Python 开发者一般会拒绝花俏的语法,而选择明确没有或者很少有歧义的语法。
同一样问题,用不同的语言解决,代码量差距还是很多的,一般情况下 Python 是 Java 的 1/5。
面向对象的思维方式
面向对象是一种思维方式,也是一门程序设计技术
要解决一个问题前,首先考虑由谁来做,怎么做事情是谁的职责,最后把事情做好就行!
对象就是谁
要解决复杂的问题,就可以找多个不同的对象,各司其职,共同实现,最终完成需求
优点
如果需要一段关键代码运行得更快或者希望某些算法不公开,可以把这部分程序用 `C` 或 `C++` 编写,然后在 `Python` 程序中使用它们
缺点
Python 源程序就是一个特殊格式的文本文件,可以使用任意文本编辑软件做 `Python` 的开发
Python 程序的文件扩展名通常都是 `.py`
print("hello world")
`print` 是 `python` 中我们学习的第一个函数
`print` 函数的作用,可以把""内部的内容,输出到屏幕上
例如使用 `pirnt("Hello world")`
NameError: name 'pirnt' is not defined
名称错误:'pirnt' 名字没有定义
SyntaxError: invalid syntax
语法错误:语法无效
每行代码负责完成一个动作
IndentationError: unexpected indent
缩进错误:不期望出现的缩进
Python 是一个格式非常严格的程序设计语言
目前而言,大家记住每行代码前面都不要增加空格
1.python的解释器
# 使用 python 2.x 解释器
python xxx.py
# 使用 python 3.x 解释器
python3 xxx.py
Python 的解释器如今有多个语言的实现,包括:
2.交互式运行python程序
直接在终端中运行解释器,而不输入要执行的文件名
在 Python 的 `Shell` 中直接输入Python 的代码,会立即看到程序执行结果
优点
适合于学习/验证 Python 语法或者局部代码
缺点
代码不能保存
不适合运行太大的程序
直接输入 `exit`
使用热键退出`ctrl + d`
IPython 中 的 “I” 代表交互 interactive
特点
IPython 是一个 python 的 **交互式 shell**,比默认的 `python shell` 好用得多
sudo apt install ipython
3.集成开发环境IDE--Pycharm
集成开发环境(`IDE`,Integrated Development Environment)—— 集成了开发软件需要的所有工具,一般包括以下工具:
PyCharm 介绍
`PyCharm` 是 Python 的一款非常优秀的集成开发环境
`PyCharm` 除了具有一般 IDE 所必备功能外,还可以在 `Windows`、`Linux`、`macOS` 下使用
`PyCharm` 适合开发大型项目
PyCharm 界面
文件导航区域能够浏览/定位/打开项目文件
文件编辑区域能够编辑当前打开的文件
控制台区域能够:
右上角的工具栏能够执行(SHIFT + F10)/ 调试(SHIFT + F9)代码
通过控制台上方的单步执行按钮(F8),可以单步执行代码
使用用自己熟悉的语言,在程序中对某些代码进行标注说明,增强程序的可读性
以 `#` 开头,`#` 右边的所有东西都被当做说明文字,而不是真正要执行的程序,只起到辅助说明作用
# 这是第一个单行注释
print("hello python")
为了保证代码的可读性,`#` 后面建议先添加一个空格,然后再编写相应的说明文字
在代码后面增加的单行注释
在程序开发时,同样可以使用 `#` 在代码的后面(旁边)增加说明性的文字
但是,需要注意的是,为了保证代码的可读性,注释和代码之间至少要有两个空格
print("hello python") # 输出 `hello python`
如果希望编写的注释信息很多,一行无法显示,就可以使用多行注释
要在 Python 程序中使用多行注释,可以用一对 连续的 三个引号(单引号和双引号都可以)
"""
这是一个多行注释
在多行注释之间,可以写很多很多的内容……
"""
print("hello python")
运算符 | 描述 | 实例 |
---|---|---|
+ | 加 | 10 + 20 = 30 |
- | 减 | 10 - 20 = -10 |
* | 乘 | 10 * 20 = 200 |
/ | 除 | 10 / 20 = 0.5 |
// | 取整数 | 返回除法的整数部分(商) 9 // 2 输出结果 4 |
% | 取余数 | 返回除法的余数 9 % 2 = 1 |
** | 幂 | 又称次方、乘方,2 ** 3 = 8 |
在 Python 中 `*` 运算符还可以用于字符串,计算结果就是字符串重复指定次数的结果
In [1]: "-" * 50
Out[1]: '----------------------------------------'
由最高到最低
运算符 | 描述 |
---|---|
** | 幂(最高优先级) |
*/%// | 乘、除、取余数、取整数 |
+- | 加法减法 |
在Python中,每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建
变量名=值
#定义qq_number的变量用来保存qq号码
qq_number="1234567"
#定义qq_password的变量用来保存qq密码
qq_password="123"
使用交互式方式,如果要查看变量内容,直接输入变量名即可,不需要使用`print`函数。
#定义qq号码变量
qq_number="1234567"
#定义qq密码变量
qq_password="123"
#在程序中,如果要输出变量的内容,需要使用print函数
print(qq_number)
print(qq_password)
使用解释器执行,如果要输出变量的内容,必须要要使用`print`函数
案例
#苹果的价格是8.5元/斤,买了7.5斤苹果,计算付款金额
#定义苹果价格变量
price=8.5
#定义购买重量
weight=7.5
#计算金额
money=price*weight
print(money)
#如果只要买苹果,就返5块钱,请重新计算购买金额
#定义苹果价格变量
price=8.5
#定义购买重量
weight=7.5
#计算金额
money=price*weight
#只要买苹果就返5元
money=money-5
print(money)
上述代码中,一共定义有几个变量?
三个:`price`/`weight`/`money`
`money=money-5`是在定义新的变量还是在使用变量?
直接使用之前已经定义的变量
变量名只有在第一次出现才是定义变量
变量名再次出现,不是定义变量,而是直接使用之前定义过的变量
在程序开发中,可以修改之前定义变量中保存的值吗?
可以
变量中存储的值,就是可以变的
在`Python`中定义变量是不需要指定类型(在其他很多高级语言中都需要)
使用`type`函数可以查看一个变量的类型
type(变量名)
不同类型变量之间的计算
1)数字型变量之间可以直接计算
在Python中,两个数字型变量是可以直接进行算数运算的
如果变量是`bool`型,在计算时
`True`对应的数字是`1`
`False`对应的数字是`0`
2)字符串变量之间使用`+`拼接字符串
在Python中,字符串之间可以使用`+`拼接生成新的字符串
first_name="三"
last_name="张"
first_name+last_name
#Out:'三张'
3)字符串变量可以和整数使用`*`重复拼接相同的字符串
"-"50
#Out[:'--------------------------------------------------'
4)数字型变量和字符串之间不能进行其他计算
变量的输入
所谓输入,就是用代码获取用户通过键盘输入的信息
在Python中,如果要获取用户在键盘上的输入信息,需要使用到`input`函数
1)关于函数
一个提前准备好的功能(别人或者自己写的代码),可以直接使用,而不用关心内部的细节
2)input函数实现键盘输入
在Python中可以使用`input`函数从键盘等待用户的输入,用户输入的任何内容Python都认为是一个字符串
字符串变量=input("提示信息:")
3)类型转换函数
|函数|说明|
|---|---|
|int(x)|将x转换为一个整数|
|float(x)|将x转换到一个浮点数|
4)变量输入演练——超市买苹果增强版
"""
收银员输入苹果的价格,单位:元/斤
收银员输入用户购买苹果的重量,单位:斤
计算并且输出付款金额
"""
#1.输入苹果单价
price_str=input("请输入苹果价格:")
#2.要求苹果重量
weight_str=input("请输入苹果重量:")
#3.计算金额
#1>将苹果单价转换成小数
price=float(price_str)
#2>将苹果重量转换成小数
weight=float(weight_str)
#3>计算付款金额
money=priceweight
print(money)
定义一个浮点变量接收用户输入的同时,就使用`float`函数进行转换
price=float(input("请输入价格:"))
变量的格式化输出
苹果单价`9.00`元/斤,购买了`5.00`斤,需要支付`45.00`元
在Python中可以使用`print`函数将信息输出到控制台
如果希望输出文字信息的同时,一起输出数据,就需要使用到格式化操作符
`%`被称为格式化操作符,专门用于处理字符串中的格式
包含`%`的字符串,被称为格式化字符串
`%`和不同的字符连用,不同类型的数据需要使用不同的格式化字符
|格式化字符|含义|
|---|---|
|%s|字符串|
|%d|有符号十进制整数,`%06d`表示输出的整数显示位数,不足的地方使用`0`补全|
|%f|浮点数,`%.2f`表示小数点后只显示两位|
|%%|输出`%`|
print("格式化字符串"%变量1)
print("格式化字符串"%(变量1,变量2...))
案例
"""
1.定义字符串变量`name`,输出我的名字叫小明,请多多关照!
2.定义整数变量`student_no`,输出我的学号是000001
3.定义小数`price`、`weight`、`money`,输出苹果单价9.00元/斤,购买了5.00斤,需要支付45.00元
4.定义一个小数`scale`,输出数据比例是10.00%
"""
name="小明"
print("我的名字叫%s,请多多关照!"%name)
student_no=1
print("我的学号是%06d"%student_no)
price=9.0
weight=5.0
money=45.0
print("苹果单价%.02f元/斤,购买%.02f斤,需要支付%.02f元"%(price,weight,money))
scale=10.0
print("数据比例是%.02f%%"%(scale))
"""
在控制台依次提示用户输入:姓名、公司、职位、电话、邮箱
按照以下格式输出:
公司名称
姓名(职位)
电话:电话
邮箱:邮箱
"""
name=input("请输入姓名:")
company=input("请输入公司:")
title=input("请输入职位:")
phone=input("请输入电话:")
email=input("请输入邮箱:")
print(company)
print()
print("%s(%s)"%(name,title))
print()
print("电话:%s"%phone)
print("邮箱:%s"%email)
标识符和关键字
标识符
标示符就是程序员定义的变量名、函数名
关键字
#通过以下命令可以查看`Python`中的关键字
import keyword
print(keyword.kwlist)
变量的命名规则
命名规则可以被视为一种惯例,并无绝对与强制
目的是为了增加代码的识别和可读性
当变量名是由二个或多个单词组成时,还可以利用驼峰命名法来命名
小驼峰式命名法
第一个单词以小写字母开始,后续单词的首字母大写
例如:`firstName`、`lastName`
大驼峰式命名法
每一个单词的首字母都采用大写字母
例如:`FirstName`、`LastName`、`CamelCase`
如果条件满足,才能做某件事情,
如果条件不满足,就做另外一件事情,或者什么也不做
判断语句又被称为“分支语句”,正是因为有了判断,才让程序有了很多的分支
在`Python`中,if语句就是用来进行判断的,格式如下:
if要判断的条件:
条件成立时,要做的事情
注意:代码的缩进为一个`tab`键,或者4个空格——建议使用空格,在Python开发中,Tab和空格不要混用!
案例
"""
1.定义一个整数变量记录年龄
2.判断是否满18岁(>=)
3.如果满18岁,允许进网吧嗨皮
"""
#1.定义年龄变量
age=18
#2.判断是否满18岁
#if语句以及缩进部分的代码是一个完整的代码块
if age>=18:
print("可以进网吧嗨皮……")
在使用`if`判断时,只能做到满足条件时要做的事情。那如果需要在不满足条件的时候,做某些事情,该如何做呢?
if要判断的条件:
条件成立时,要做的事情
else:
条件不成立时,要做的事情
案例
"""
1.输入用户年龄
2.判断是否满18岁(>=)
3.如果满18岁,允许进网吧嗨皮
4.如果未满18岁,提示回家写作业
"""
#1.输入用户年龄
age=int(input("今年多大了?"))
#2.判断是否满18岁
#if语句以及缩进部分的代码是一个完整的语法块
if age>=18:
print("可以进网吧嗨皮……")
else:
print("你还没长大,应该回家写作业!")
在程序开发中,通常在判断条件时,会需要同时判断多个条件
只有多个条件都满足,才能够执行后续代码,这个时候需要使用到逻辑运算符
逻辑运算符可以把多个条件按照逻辑进行连接,变成更复杂的条件
Python中的逻辑运算符包括:与and/或or/非not三种
`and`
条件1 and 条件2
与/并且
两个条件同时满足,返回`True`
只要有一个不满足,就返回`False`
|条件1|条件2|结果|
|:---:|:---:|:---:|
|成立|成立|成立|
|成立|不成立|不成立|
|不成立|成立|不成立|
|不成立|不成立|不成立|
`or`
条件1or条件2
或/或者
两个条件只要有一个满足,返回`True`
两个条件都不满足,返回`False`
|条件1|条件2|结果|
|:---:|:---:|:---:|
|成立|成立|成立|
|成立|不成立|成立|
|不成立|成立|成立|
|不成立|不成立|不成立|
`not`
not条件
非/不是
|条件|结果|
|:---:|:---:|
|成立|不成立|
|不成立|成立|
案例
"""
1.练习1:定义一个整数变量`age`,编写代码判断年龄是否正确
要求人的年龄在0-120之间
2.练习2:定义两个整数变量`python_score`、`c_score`,编写代码判断成绩
要求只要有一门成绩>60分就算合格
3.练习3:定义一个布尔型变量`is_employee`,编写代码判断是否是本公司员工
如果不是提示不允许入内
"""
#练习1:定义一个整数变量age,编写代码判断年龄是否正确
age=100
#要求人的年龄在0-120之间
if age>=0 and age<=120:
print("年龄正确")
else:
print("年龄不正确")
#练习2:定义两个整数变量python_score、c_score,编写代码判断成绩
python_score=50
c_score=50
#要求只要有一门成绩>60分就算合格
if python_score>60 or c_score>60:
print("考试通过")
else:
print("再接再厉!")
#练习3:定义一个布尔型变量`is_employee`,编写代码判断是否是本公司员工
is_employee=True
#如果不是提示不允许入内
if not is_employee:
print("非公勿内")
`elif`
if条件1:
条件1满足执行的代码
elif条件2:
条件2满足时,执行的代码
elif条件3:
条件3满足时,执行的代码
else:
以上条件都不满足时,执行的代码
`if`的嵌套
if条件1:
条件1满足执行的代码
if条件1基础上的条件2:
条件2满足时,执行的代码
#条件2不满足的处理
else:
条件2不满足时,执行的代码
#条件1不满足的处理
else:
条件1不满足时,执行的代码
猜拳游戏
"""
1.从控制台输入要出的拳——石头(1)/剪刀(2)/布(3)
2.电脑随机出拳——先假定电脑只会出石头,完成整体代码功能
3.比较胜负
|序号|规则|
|:---:|:---:|
|1|石头胜剪刀|
|2|剪刀胜布|
|3|布胜石头|
"""
player=int(input("请出拳石头(1)/剪刀(2)/布(3):"))
#电脑随机出拳-假定电脑永远出石头
computer=1
#比较胜负
#如果条件判断的内容太长,可以在最外侧的条件增加一对大括号
#再在每一个条件之间,使用回车,PyCharm可以自动增加8个空格
if ((player==1 and computer==2) or
(player==2 and computer==3) or
(player==3 and computer==1)):
print("噢耶!!!电脑弱爆了!!!")
elif player==computer:
print("心有灵犀,再来一盘!")
else:
print("不行,我要和你决战到天亮!")
随机数的处理
在`Python`中,要使用随机数,首先需要导入随机数的模块——“工具包”
import random
`random.randint(a,b)`,返回`[a,b]`之间的整数,包含`a`和`b`
random.randint(12,20)#生成的随机数n:12<=n<=20
random.randint(20,20)#结果永远是20
random.randint(20,10)#该语句是错误的,下限必须小于上限
#猜拳游戏改进,电脑随机出拳
import random
player=int(input("请出拳石头(1)/剪刀(2)/布(3):"))
#电脑随机出拳-假定电脑永远出石头
computer=random.randint(1,3)
#比较胜负
#如果条件判断的内容太长,可以在最外侧的条件增加一对大括号
#再在每一个条件之间,使用回车,PyCharm可以自动增加8个空格
if ((player==1 and computer==2) or
(player==2 and computer==3) or
(player==3 and computer==1)):
print("噢耶!!!电脑弱爆了!!!")
elif player==computer:
print("心有灵犀,再来一盘!")
else:
print("不行,我要和你决战到天亮!")
是完成基本的算术运算使用的符号,用来处理四则运算
|运算符|描述|实例|
|:---:|:---:|---|
|+|加|10+20=30|
|-|减|10-20=-10|
||乘|10*20=200|
|/|除|10/20=0.5|
|//|取整除|返回除法的整数部分(商)9//2输出结果4|
|%|取余数|返回除法的余数9%2=1|
||幂|又称次方、乘方,2**3=8|
|运算符|描述|
|---|---|
|==|检查两个操作数的值是否相等,如果是,则条件成立,返回True|
|!=|检查两个操作数的值是否不相等,如果是,则条件成立,返回True|
|>|检查左操作数的值是否大于右操作数的值,如果是,则条件成立,返回True|
|<|检查左操作数的值是否小于右操作数的值,如果是,则条件成立,返回True|
|>=|检查左操作数的值是否大于或等于右操作数的值,如果是,则条件成立,返回True|
|<=|检查左操作数的值是否小于或等于右操作数的值,如果是,则条件成立,返回True|
|运算符|逻辑表达式|描述|
|---|---|---|
|and|x and y|只有x和y的值都为True,才会返回True
否则只要x或者y有一个值为False,就返回False|
|or|x or y|只要x或者y有一个值为True,就返回True
只有x和y的值都为False,才会返回False|
|not|not x|如果x为True,返回False
如果x为False,返回True|
在Python中,使用`=`可以给变量赋值
在算术运算时,为了简化代码的编写,`Python`还提供了一系列的与算术运算符对应的赋值运算符
注意:赋值运算符中间不能使用空格
|运算符|描述|实例|
|---|---|---|
|=|简单的赋值运算符|c=a+b将a+b的运算结果赋值为c|
|+=|加法赋值运算符|c+=a等效于c=c+a|
|-=|减法赋值运算符|c-=a等效于c=c-a|
|*=|乘法赋值运算符|c*=a等效于c=ca|
|/=|除法赋值运算符|c/=a等效于c=c/a|
|//=|取整除赋值运算符|c//=a等效于c=c//a|
|%=|取模(余数)赋值运算符|c%=a等效于c=c%a|
|**=|幂赋值运算符|c**=a等效于c=c**a|
以下表格的算数优先级由高到最低顺序排列
|运算符|描述|
|---|---|
|**|幂(最高优先级)|
|*/%//|乘、除、取余数、取整除|
|+-|加法、减法|
|<= < > >=|比较运算符|
|== !=|等于运算符|
|*= %= /= //= -= += ==|赋值运算符|
|not or and|逻辑运算符|
在程序开发中,一共有三种流程方式:
循环的作用就是让指定的代码重复的执行
初始条件设置——通常是重复执行的计数器
while条件(判断计数器是否达到目标次数):
条件满足时,做的事情1
条件满足时,做的事情2
条件满足时,做的事情3
...(省略)...
处理条件(计数器+1)
#打印5遍HelloPython
#1.定义重复次数计数器
i=1
#2.使用while判断条件
while i<=5:
#要重复执行的代码
print("HelloPython")
#处理计数器i
i=i+1
print("循环结束后的i=%d"%i)
注意:循环结束后,之前定义的计数器条件的数值是依旧存在的
死循环:由于程序员的原因,忘记在循环内部修改循环的判断条件,导致循环持续执行,程序无法终止!
循环计算
在程序开发中,通常会遇到利用循环重复计算的需求
#计算0~100之间所有数字的累计求和结果
#0.定义最终结果的变量
result=0
#1.定义一个整数的变量记录循环的次数
i=0
#2.开始循环
while i<=100:
print(i)
#每一次循环,都让result这个变量和i这个计数器相加
result+=i
#处理计数器
i+=1
print("0~100之间的数字求和结果=%d"%result)
#计算0~100之间所有偶数的累计求和结果
#1.编写循环确认要计算的数字
#2.添加结果变量,在循环内部处理计算结果
#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)
break
在循环过程中,如果某一个条件满足后,不再希望循环继续执行,可以使用`break`退出循环
i=0
while i<10:
#break某一条件满足时,退出循环,不再执行后续重复的代码
#i==3
if i==3:
break
print(i)
i+=1
print("over")
在循环过程中,如果某一个条件满足后,不希望执行循环代码,但是又不希望退出循环,可以使用`continue`
也就是:在整个循环中,只有某些条件,不需要执行循环代码,而其他条件都需要执行
i=0
while i<10:
#当i==7时,不希望执行需要重复执行的代码
if i==7:
#在使用continue之前,同样应该修改计数器,否则会出现死循环
i+=1
continue
#重复执行的代码
print(i)
i+=1
注意:使用`continue`时,条件处理部分的代码,需要特别注意,不小心会出现死循环
`while`嵌套就是:`while`里面还有`while`
while条件1:
条件满足时,做的事情1
条件满足时,做的事情2
条件满足时,做的事情3
...(省略)...
while条件2:
条件满足时,做的事情1
条件满足时,做的事情2
条件满足时,做的事情3
...(省略)...
处理条件2
处理条件1
案例
#在控制台连续输出五行`*`,每一行星号的数量依次递增
#使用字符串打印
#1.定义一个计数器变量,从数字1开始,循环会比较方便
row=1
while row<=5:
print("*"*row)
row+=1
在默认情况下,`print`函数输出内容之后,会自动在内容末尾增加换行
如果不希望末尾增加换行,可以在`print`函数输出内容的后面增加`,end=""`
其中`""`中间可以指定`print`函数输出内容之后,继续希望显示的内容
"""
在控制台连续输出五行`*`,每一行星号的数量依次递增
1>完成5行内容的简单输出
2>分析每行内部的`*`应该如何处理?
每行显示的星星和当前所在的行数是一致的
嵌套一个小的循环,专门处理每一行中`列`的星星显示
"""
row=1
while row<=5:
#假设python没有提供字符串操作
#在循环内部,再增加一个循环,实现每一行的星星打印
col=1
while col<=row:
print("*",end="")
col+=1
#每一行星号输出完成后,再增加一个换行
print("")
row+=1
九九乘法表
"""
1.打印9行小星星
2.将每一个`*`替换成对应的行与列相乘
"""
#定义起始行
row=1
#最大打印9行
while row<=9:
#定义起始列
col=1
#最大打印row列
while col<=row:
#end="",表示输出结束后,不换行
#"\t"可以在控制台输出一个制表符,协助在输出文本时对齐
print("%d*%d=%d"%(col,row,row*col),end="\t")
#列数+1
col+=1
#一行打印完成的换行
print("")
#行数+1
row+=1
字符串中的转义字符
`\t`在控制台输出一个制表符,协助在输出文本时垂直方向保持对齐
`\n`在控制台输出一个换行符
制表符的功能是在不使用表格的情况下在垂直方向按列对齐文本
|转义字符|描述|
|---|---|
|\\|反斜杠符号|
|\'|单引号|
|\"|双引号|
|\n|换行|
|\t|横向制表符|
|\r|回车|
所谓函数,就是把具有独立功能的代码块组织为一个小模块,在需要的时候调用
函数的使用包含两个步骤:
函数的作用,在开发程序时,使用函数可以提高编写的效率以及代码的重用
#定义函数的格式如下:
def 函数名():
函数封装的代码
def multiple():
"""
1.打印9行小星星
2.将每一个`*`替换成对应的行与列相乘
"""
# 定义起始行
row = 1
# 最大打印9行
while row <= 9:
# 定义起始列
col = 1
# 最大打印row列
while col <= row:
# end="",表示输出结束后,不换行
# "\t"可以在控制台输出一个制表符,协助在输出文本时对齐
print("%d*%d=%d" % (col, row, row * col), end="\t")
# 列数+1
col += 1
# 一行打印完成的换行
print("")
# 行数+1
row += 1
multiple()
在开发中,如果希望给函数添加注释,应该在定义函数的下方,使用连续的三对引号
在函数调用位置,使用快捷键`CTRL+Q`可以查看函数的说明信息
注意:因为函数体相对比较独立,函数定义的上方,应该和其他代码保留两个空行
#在函数名的后面的小括号内部填写参数,多个参数之间使用`,`分隔
def sum_num(num1,num2):
result=num1+num2
print("%d+%d=%d"%(num1,num2,result))
sum_num(50,20)
参数的作用
函数的参数,增加函数的通用性,针对相同的数据处理逻辑,能够适应更多的数据
在函数内部,把参数当做变量使用,进行需要的数据处理
函数调用时,按照函数定义的参数顺序,把希望在函数内部处理的数据,通过参数传递
形参和实参
形参:定义函数时,小括号中的参数,是用来接收参数用的,在函数内部作为变量使用
实参:调用函数时,小括号中的参数,是用来把数据传递到函数内部用的
在程序开发中,有时候,会希望一个函数执行结束后,告诉调用者一个结果,以便调用者针对具体的结果做后续的处理
返回值是函数完成工作后,最后给调用者的一个结果
在函数中使用`return`关键字可以返回结果
调用函数一方,可以使用变量来接收函数的返回结果
def sum_2_num(num1,num2):
"""对两个数字的求和"""
return num1+num2
#调用函数,并使用result变量接收计算结果
result=sum_2_num(10,20)
print("计算结果是%d"%result)
一个函数里面又调用了另外一个函数,这就是函数嵌套调用
如果函数`test2`中,调用了另外一个函数`test1`
那么执行到调用`test1`函数时,会先把函数`test1`中的任务都执行完
才会回到`test2`中调用函数`test1`的位置,继续执行后续的代码
def test1():
print("*"*50)
print("test1")
print("*"*50)
def test2():
print("-"*50)
print("test2")
test1()
print("-"*50)
test2()
#定义一个函数能够打印5行的分隔线,要求符合打印任意重复次数的任意类型分隔线
def print_line(char,times):
print(char*times)
def print_lines(char,times):
"""
打印分割线
:param char: 分割字符
:param times: 字符个数
:return:
"""
row=0
while row<5:
print_line(char,times)
row+=1
print_lines("*",5)
模块名也是一个标识符
注意:如果在给Python文件起名时,以数字开头是无法在`PyCharm`中通过导入这个模块的
在`Python`中,所有非数字型变量都支持以下特点:
都是一个序列`sequence`,也可以理解为容器
取值`[]`
遍历`for in`
计算长度、最大/最小值、比较、删除
链接`+`和重复`*`
切片
列表的定义
`List`(列表)是`Python`中使用最频繁的数据类型,在其他语言中通常叫做数组
专门用于存储一串信息
列表用`[]`定义,数据之间使用`,`分隔
列表的索引从`0`开始
name_list=["zhangsan","lisi","wangwu"]
列表常用操作
|序号|分类|关键字/函数/方法|说明|
|---|---|---|---|
|1|增加|列表.insert(索引,数据)|在指定位置插入数据|
|||列表.append(数据)|在末尾追加数据
|||列表.extend(列表2)|将列表2的数据追加到列表|
|2|修改|列表[索引]=数据|修改指定索引的数据|
|3|删除|del列表[索引]|删除指定索引的数据|
|||列表.remove[数据]|删除第一个出现的指定数据|
|||列表.pop|删除末尾数据|
|||列表.pop(索引)|删除指定索引数据|
|||列表.clear|清空列表|
|4|统计|len(列表)|列表长度|
|||列表.count(数据)|数据在列表中出现的次数|
|5|排序|列表.sort()|升序排序|
|||列表.sort(reverse=True)|降序排序|
|||列表.reverse()|逆序、反转|
del关键字
`del`关键字本质上是用来将一个变量从内存中删除的
如果使用`del`关键字将变量从内存中删除,后续的代码就不能再使用这个变量了
del name_list
循环遍历
遍历就是从头到尾依次从列表中获取数据
在循环体内部针对每一个元素,执行相同的操作
在`Python`中为了提高列表的遍历效率,专门提供的迭代iteration遍历
使用`for`就能够实现迭代遍历
#for循环内部使用的变量in列表
for name in name_list:
#循环内部针对列表元素进行操作
print(name)
应用场景
尽管`Python`的列表中可以存储不同类型的数据
但是在开发中,更多的应用场景是
元组的定义
info_tuple=("zhangsan",18,1.75)
#创建空元组
info_tuple=()
#元组中只包含一个元素时,需要在元素后面添加逗号
info_tuple=(50,)
元组常用操作
info_tuple.count("zhangsan")#计算出现次数
info_tuple.index("zhangsan")#取索引
在`Python`中,可以使用`for`循环遍历所有非数字型类型的变量:列表、元组、字典以及字符串
尽管可以使用`for in`遍历元组
但是在开发中,更多的应用场景是:
info=("zhangsan",18)
print("%s的年龄是%d"%info)
元组和列表之间的转换
使用`list`函数可以把元组转换成列表
list(元组)
使用`tuple`函数可以把列表转换成元组
tuple(列表)
字典的定义
xiaoming={"name":"小明",
"age":18,
"gender":True,
"height":1.75}
字典常用操作
#定义一个字典
xiaoming={"name":"小明",
"gender":True,
"height":1.75}
#取值
xiaoming["name"]
#增加
xiaoming["age"]=18
#修改
xiaoming["name"]="大名"
#字典能够使用的函数
xiaoming.clear()#清空字典
xiaoming.items
xiaoming.setdefault
xiaoming.copy
xiaoming.keys
xiaoming.update(字典2)#合并字典,覆盖更新
xiaoming.fromkey
sxiaoming.pop
xiaoming.values
xiaoming.get
xiaoming.popitem
循环遍历
#for循环内部使用的`key的变量`in字典
for k in xiaoming:
print("%s:%s"%(k,xiaoming[k]))
应用场景
尽管可以使用`for in`遍历字典
但是在开发中,更多的应用场景是:
card_list=[{"name":"张三",
"qq":"12345",
"phone":"110"},
{"name":"李四",
"qq":"54321",
"phone":"10086"}]
for k in card_list:
print(k)
字符串的定义
大多数编程语言都是用`"`来定义字符串
string="Hello Python"
for c in string:
print(c)
字符串的常用操作
1)判断类型-9
|方法|说明|
|---|---|
|string.isspace()|如果string中只包含空格,则返回True|
|string.isalnum()|如果string至少有一个字符并且所有字符都是字母或数字则返回True|
|string.isalpha()|如果string至少有一个字符并且所有字符都是字母则返回True|
|string.isdecimal()|如果string只包含数字则返回True,`全角数字`|
|string.isdigit()|如果string只包含数字则返回True,`全角数字`、`\u00b2`|
|string.isnumeric()|如果string只包含数字则返回True,`全角数字`,`\u00b2`,`汉字数字`|
|string.istitle()|如果string是标题化的(每个单词的首字母大写)则返回True|
|string.islower()|如果string中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回True|
|string.isupper()|如果string中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回True|
2)查找和替换-7
|方法|说明|
|---|---|
|string.startswith(str)|检查字符串是否是以str开头,是则返回True|
|string.endswith(str)|检查字符串是否是以str结束,是则返回True|
|string.find(str,start=0,end=len(string))|检测str是否包含在string中,如果start和end指定范围,则检查是否包含在指定范围内,如果是返回开始的索引值,否则返回`-1`|
|string.rfind(str,start=0,end=len(string))|类似于find(),不过是从右边开始查找|
|string.index(str,start=0,end=len(string))|跟find()方法类似,不过如果str不在string会报错|
|string.rindex(str,start=0,end=len(string))|类似于index(),不过是从右边开始|
|string.replace(old_str,new_str,num=string.count(old))|把string中的old_str替换成new_str,如果num指定,则替换不超过num次|
3)大小写转换-5
|方法|说明|
|---|---|
|string.capitalize()|把字符串的第一个字符大写|
|string.title()|把字符串的每个单词首字母大写|
|string.lower()|转换string中所有大写字符为小写|
|string.upper()|转换string中的小写字母为大写|
|string.swapcase()|翻转string中的大小写|
4)文本对齐-3
|方法|说明|
|---|---|
|string.ljust(width)|返回一个原字符串左对齐,并使用空格填充至长度width的新字符串|
|string.rjust(width)|返回一个原字符串右对齐,并使用空格填充至长度width的新字符串|
|string.center(width)|返回一个原字符串居中,并使用空格填充至长度width的新字符串|
5)去除空白字符-3
|方法|说明|
|---|---|
|string.lstrip()|截掉string左边(开始)的空白字符|
|string.rstrip()|截掉string右边(末尾)的空白字符|
|string.strip()|截掉string左右两边的空白字符|
6)拆分和连接-5
|方法|说明|
|---|---|
|string.partition(str)|把字符串string分成一个3元素的元组(str前面,str,str后面)|
|string.rpartition(str)|类似于partition()方法,不过是从右边开始查找|
|string.split(str="",num)|以str为分隔符拆分string,如果num有指定值,则仅分隔num+1个子字符串,str默认包含'\r','\t','\n'和空格|
|string.splitlines()|按照行('\r','\n','\r\n')分隔,返回一个包含各行作为元素的列表|
|string.join(seq)|以string作为分隔符,将seq中所有的元素(的字符串表示)合并为一个新的字符串|
字符串的切片
字符串[开始索引:结束索引:步长]
注意:
索引的顺序和倒序
在Python中不仅支持顺序索引,同时还支持倒序索引
所谓倒序索引就是从右向左计算索引
最右边的索引值是-1,依次递减
num_str="0123456789"
#1.截取从2~5位置的字符串
print(num_str[2:6])
#2.截取从2~`末尾`的字符串
print(num_str[2:])
#3.截取从`开始`~5位置的字符串
print(num_str[:6])
#4.截取完整的字符串
print(num_str[:])
#5.从开始位置,每隔一个字符截取字符串
print(num_str[::2])
#6.从索引1开始,每隔一个取一个
print(num_str[1::2])
#倒序切片
#-1表示倒数第一个字符
print(num_str[-1])
#7.截取从2~`末尾-1`的字符串
print(num_str[2:-1])
#8.截取字符串末尾两个字符
print(num_str[-2:])
#9.字符串的逆序(面试题)
print(num_str[::-1])
Python内置函数
Python包含了以下内置函数:
|函数|描述|备注|
|---|---|---|
|len(item)|计算容器中元素个数||
|del(item)|删除变量|del有两种方式|
|max(item)|返回容器中元素最大值|如果是字典,只针对key比较|
|min(item)|返回容器中元素最小值|如果是字典,只针对key比较|
注意:字符串比较符合以下规则:"0"<"A"<"a",字典不能比较大小
切片
|描述|Python表达式|结果|支持的数据类型|
|:---:|---|---|---|---|
|切片|"0123456789"[::-2]|"97531"|字符串、列表、元组|
运算符
|运算符|Python表达式|结果|描述|支持的数据类型|
|:---:|---|---|---|---|
|+|[1,2]+[3,4]|[1,2,3,4]|合并|字符串、列表、元组|
|*|["Hi!"]*4|['Hi!','Hi!','Hi!','Hi!']|重复|字符串、列表、元组|
|in|3 in (1,2,3)|True|元素是否存在|字符串、列表、元组、字典|
|not in|4 not in(1,2,3)|True|元素是否不存在|字符串、列表、元组、字典|
|> >= == < <=|(1,2,3)<(2,2,3)|True|元素比较|字符串、列表、元组|
注意
完整的for循环语法
for变量in集合:
循环体代码
else:
没有通过break退出循环,循环结束后,会执行的代码
应用场景
在迭代遍历嵌套的数据类型时,例如一个列表包含了多个字典
需求:要判断某一个字典中是否存在指定的值
如果存在,提示并且退出循环
如果不存在,在循环整体结束后,希望得到一个统一的提示
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("循环结束")
1.程序启动,显示名片管理系统欢迎界面,并显示功能菜单
欢迎使用【名片管理系统】V1.0
2.用户用数字选择不同的功能
3.根据功能选择,执行不同的功能
4.用户名片需要记录用户的姓名、电话、QQ、邮件
5.如果查询到指定的名片,用户可以选择修改或者删除名片
搭建名片管理系统框架结构
1.文件准备
新建`cards_main.py`保存主程序功能代码
新建`cards_tools.py`保存所有名片功能函数
2.编写主运行循环
在`cards_main`中添加一个无限循环
while True:
#在`#`后跟上`TODO`,用于标记需要去做的工作
# TODO(小明)显示系统菜单
action=input("请选择操作功能:")
print("您选择的操作是:%s"%action)
#根据用户输入决定后续的操作
if action in["1","2","3"]:
#新增名片
if action == "1":
pass
#显示全部
elif action == "2":
pass
#查询名片
elif action == "3":
pass
pass#`pass`就是一个空语句,不做任何事情,一般用做占位语句,为了保持程序结构的完整性
elif action=="0":
print("欢迎再次使用【名片管理系统】")
break
else:
print("输入错误,请重新输入")
3.在`cards_tools`中增加四个新函数
def show_menu():
"""
显示菜单
"""
print("*"*50)
print("欢迎使用【菜单管理系统】")
print("")
print("1.新建名片")
print("2.显示全部")
print("3.查询名片")
print("")
print("0.退出系统")
print("*"*50)
pass
def new_card():
"""
新建名片
"""
print("-"*50)
print("功能:新建名片")
def show_all():
"""
显示全部
"""
print("-"*50)
print("功能:显示全部")
def search_card():
"""
搜索名片
"""
print("-"*50)
print("功能:搜索名片")
4.导入模块
在`cards_main.py`中使用`import`导入`cards_tools`模块
import cards_tools
while True:
# TODO(小明)显示系统菜单
cards_tools.show_menu()
action=input("请选择操作功能:")
print("您选择的操作是:%s"%action)
#根据用户输入决定后续的操作
if action in["1","2","3"]:
#新增名片
if action == "1":
cards_tools.new_card()
#显示全部
elif action == "2":
cards_tools.show_all()
#查询名片
elif action == "3":
cards_tools.search_card()
pass#`pass`就是一个空语句,不做任何事情,一般用做占位语句,为了保持程序结构的完整性
elif action=="0":
print("欢迎再次使用【名片管理系统】")
break
else:
print("输入错误,请重新输入")
程序就是用来处理数据的,而变量就是用来存储数据的
定义名片列表变量
#所有名片记录的列表
card_list=[]
注意
功能分析
实现new_card方法
def new_card():
"""
新建名片
"""
print("-"*50)
print("功能:新建名片")
# 1.提示用户输入名片信息
name = input("请输入姓名:")
phone = input("请输入电话:")
qq = input("请输入QQ号码:")
email = input("请输入邮箱:")
# 2.将用户信息保存到一个字典
card_dict = {"name": name,
"phone": phone,
"qq": qq,
"email": email}
# 3.将用户字典添加到名片列表
card_list.append(card_dict)
print(card_list)
# 4.提示添加成功信息
print("成功添加%s的名片" % card_dict["name"])
技巧:在`PyCharm`中,可以使用`SHIFT+F6`统一修改变量名
功能分析
增加没有名片记录判断
实现show_card方法
def show_all():
"""
显示全部
"""
print("-"*50)
print("功能:显示全部")
if len(card_list) == 0:
print("提示:没有任何名片记录")
return
# 打印表头
for name in["姓名", "电话", "QQ", "邮箱"]:
print(name, end="\t\t")
print("")
# 打印分隔线
print("="*50)
for card_dict in card_list:
print("%s\t\t%s\t\t%s\t\t%s" % (card_dict["name"],
card_dict["phone"],
card_dict["qq"],
card_dict["email"]))
注意
功能分析
实现search_card方法
def search_card():
"""
搜索名片
"""
print("-"*50)
print("功能:搜索名片")
# 1.提示要搜索的姓名
find_name = input("请输入要搜索的姓名:")
# 2.遍历字典
for card_dict in card_list:
if card_dict["name"] == find_name:
print("姓名\t\t\t电话\t\t\tQQ\t\t\t邮箱")
print("-"*40)
print("%s\t\t\t%s\t\t\t%s\t\t\t%s" % (
card_dict["name"],
card_dict["phone"],
card_dict["qq"],
card_dict["email"]))
print("-"*40)
deal_card(card_dict)
break
else:
print("没有找到%s" % find_name)
def deal_card(find_dict):
"""
处理查找到的名片
:param find_dict:查找到的名片
:return:
"""
print(find_dict)
action_str = input("请选择要执行的操作"
"[1]修改[2]删除")
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("%s的名片修改成功" % find_dict["name"])
print("修改")
elif action_str == "2":
card_list.remove(find_dict)
print("删除")
def input_card_info(dict_value,tip_message):
"""
输入名片信息
:param dict_value:字典中原有的值
:param tip_message: 输入的提示文字
:return:如果用户输入了内容就返回内容,否则返会字典中原有的值
"""
#1.提示用户输入内容
result_str=input(tip_message)
#2.针对用户的输入进行判断,如果用户输入了内容,直接返回结果
if len(result_str)>0:
return result_str
#3.如果用户没有输入内容,返回`字典中原有的值`
else:
return dict_value
LINUX上的`Shebang`符号(`#!`)
使用Shebang的步骤
1.使用`which`查询`python3`解释器所在路径
which python3
2.修改要运行的主python文件,在第一行增加以下内容
#!/usr/bin/python3
3.修改主python文件的文件权限,增加执行权限
chmod +x cards_main.py
4.在需要时执行程序即可
./cards_main.py
cards_main.py
import cards_tools
while True:
cards_tools.show_menu()
action=input("请选择操作功能:")
print("您选择的操作是:%s"%action)
#根据用户输入决定后续的操作
if action in["1","2","3"]:
#新增名片
if action == "1":
cards_tools.new_card()
#显示全部
elif action == "2":
cards_tools.show_all()
#查询名片
elif action == "3":
cards_tools.search_card()
pass#`pass`就是一个空语句,不做任何事情,一般用做占位语句,为了保持程序结构的完整性
elif action=="0":
print("欢迎再次使用【名片管理系统】")
break
else:
print("输入错误,请重新输入")
cards_tools.py
card_list=[]
def show_menu():
"""
显示菜单
"""
print("*"*50)
print("欢迎使用【菜单管理系统】")
print("")
print("1.新建名片")
print("2.显示全部")
print("3.查询名片")
print("")
print("0.退出系统")
print("*"*50)
pass
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的名片" % card_dict["name"])
def show_all():
"""
显示全部
"""
print("-"*50)
print("功能:显示全部")
if len(card_list) == 0:
print("提示:没有任何名片记录")
return
# 打印表头
for name in["姓名", "电话", "QQ", "邮箱"]:
print(name, end="\t\t")
print("")
# 打印分隔线
print("="*50)
for card_dict in card_list:
print("%s\t\t%s\t\t%s\t\t%s" % (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("姓名\t\t\t电话\t\t\tQQ\t\t\t邮箱")
print("-"*40)
print("%s\t\t\t%s\t\t\t%s\t\t\t%s" % (
card_dict["name"],
card_dict["phone"],
card_dict["qq"],
card_dict["email"]))
print("-"*40)
deal_card(card_dict)
break
else:
print("没有找到%s" % find_name)
def deal_card(find_dict):
"""
处理查找到的名片
:param find_dict:查找到的名片
:return:
"""
print(find_dict)
action_str = input("请选择要执行的操作"
"[1]修改[2]删除")
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("%s的名片修改成功" % find_dict["name"])
print("修改")
elif action_str == "2":
card_list.remove(find_dict)
print("删除")
def input_card_info(dict_value,tip_message):
"""
输入名片信息
:param dict_value:字典中原有的值
:param tip_message: 输入的提示文字
:return:如果用户输入了内容就返回内容,否则返会字典中原有的值
"""
#1.提示用户输入内容
result_str=input(tip_message)
#2.针对用户的输入进行判断,如果用户输入了内容,直接返回结果
if len(result_str)>0:
return result_str
#3.如果用户没有输入内容,返回`字典中原有的值`
else:
return dict_value
变量的引用
引用的概念
注意:如果变量已经被定义,当给一个变量赋值的时候,本质上是修改了数据的引用
函数的参数和返回值的传递
在`Python`中,函数的实参/返回值都是是靠引用来传递来的
不可变类型,内存中的数据不允许被修改:
可变类型,内存中的数据可以被修改:
注意
哈希`(hash)`
`Python`中内置有一个名字叫做`hash(o)`的函数
`哈希`是一种算法,其作用就是提取数据的特征码(指纹)
在`Python`中,设置字典的键值对时,会首先对`key`进行`hash`已决定如何在内存中保存字典的数据,以方便后续对字典的操作:增、删、改、查
局部变量
局部变量的生命周期
全局变量
如果在函数中需要修改全局变量,需要使用`global`进行声明
注意:函数执行时,需要处理变量时会:
全局变量命名的建议
定义函数时,是否接收参数,或者是否返回结果,是根据实际的功能需求来决定的!
1.无参数,无返回值
此类函数,不接收参数,也没有返回值,应用场景如下:
如果全局变量的数据类型是一个可变类型,在函数内部可以使用方法修改全局变量的内容——变量的引用不会改变
在函数内部,使用赋值语句才会修改变量的引用
2.无参数,有返回值
此类函数,不接收参数,但是有返回值,应用场景如下:
3.有参数,无返回值
此类函数,接收参数,没有返回值,应用场景如下:
4.有参数,有返回值
此类函数,接收参数,同时有返回值,应用场景如下:
一个函数执行后能否返回多个结果?
在利用元组在返回温度的同时,也能够返回湿度
def measure():
"""返回当前的温度"""
print("开始测量...")
temp=39
wetness=10
print("测量结束...")
return(temp,wetness)
temp,wetness=measure()
print(temp,wetness)
面试题——交换两个数字
题目要求
#解法1-使用临时变量
a=6
b=100
c=b
b=a
a=c
print(a,b)
#解法2-不使用临时变量
a=a+b
b=a-b
a=a-b
#解法3——Python专有,利用元组
a,b=b,a
1.不可变和可变的参数
问题1:在函数内部,针对参数使用赋值语句,会不会影响调用函数时传递的实参变量?——不会!
问题2:如果传递的参数是可变类型,在函数内部,使用方法修改了数据的内容,同样会影响到外部的数据
面试题——`+=`
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))
print_info("wps")
print_info("wps",False)
提示
缺省参数的注意事项
1)缺省参数的定义位置
def print_info(name,gender=True,title):
2)调用带有多个缺省参数的函数
def print_info(name,title="",gender=True):
3. 多值参数
定义支持多值参数的函数
def demo(num,*args,**kwargs):
print(num)
print(args)
print(kwargs)
demo(1,2,3,4,5,name="小明",age=18,gender=True)
多值参数案例——计算任意多个数字的和
需求
def sum_numbers(*args):
num=0
#遍历args元组顺序求和
for n in args:
num+=n
return num
print(sum_numbers(1,2,3,4,5,6,7,8,9))
元组和字典的拆包(知道)
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.递归函数的特点
特点
代码特点
def sum_numbers(num):
print(num)
#递归的出口很重要,否则会出现死循环
if num==1:
return
sum_numbers(num-1)
sum_numbers(3)
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(2))
1.过程和函数
2.面相过程
3.面向对象
相比较函数,面向对象是更大的封装,根据职责在一个对象中封装多个方法
1.类和对象的概念
类
对象
在程序开发中,应该先有类,再有对象
2.类和对象的关系
3.类的设计
在使用面相对象开发前,应该首先分析需求,确定一下,程序中需要包含哪些类!
在程序开发中,要设计一个类,通常需要满足一下三个要素:
大驼峰命名法
`CapWords`
类名的确定
属性和方法的确定
1.`dir`内置函数
在`Python`中对象几乎是无所不在的,我们之前学习的变量、数据、函数都是对象
在`Python`中可以使用以下方法验证:
提示`__方法名__`格式的方法是`Python`提供的内置方法/属性
|序号|方法名|类型|作用|
|:---:|:---:|:---:|---|
|01|`__new__`|方法|创建对象时,会被自动调用|
|02|`__init__`|方法|对象被初始化时,会被自动调用|
|03|`__del__`|方法|对象被从内存中销毁前,会被自动调用|
|04|`__str__`|方法|返回对象的描述信息,`print`函数输出使用|
2.定义简单的类(只包含方法)
面向对象是更大的封装,在一个类中封装多个方法,这样通过这个类创建出来的对象,就可以直接调用这些方法了!
定义只包含方法的类
class 类名:
def 方法1(self,参数列表):
pass
def 方法2(self,参数列表):
pass
注意:类名的命名规则要符合大驼峰命名法
创建对象
当一个类定义完成之后,要使用这个类来创建对象,语法格式如下:
对象变量=类名()
第一个面向对象程序
需求
分析
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.drink()
tom.eat()
lazy_cat=Cat()
lazy_cat.eat()
lazy_cat.drink()
lazy_cat2=lazy_cat
`tom`和`lazy_cat`不是同一个对象,`lazy_cat2`和`lazy_cat`是同一个对象
3.方法中的`self`参数
给对象增加属性
tom.name="Tom"
提示
使用`self`在方法内部输出每一只猫的名字
由哪一个对象调用的方法,方法内的`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()
4.初始化方法
`__init__`方法是专门用来定义一个类具有哪些属性的方法!
在`Cat`中增加`__init__`方法,验证该方法在创建对象时会被自动调用
class Cat:
"""这是一个猫类"""
def __init__(self):
print("初始化方法")
在初始化方法内部定义属性
在`__init__`方法内部使用`self.属性名=属性的初始值`就可以定义属性
定义属性之后,再使用`Cat`类创建的对象,都会拥有该属性
class Cat:
def __init__(self):
print("这是一个初始化方法")
#定义用Cat类创建的猫对象都有一个name的属性
self.name="Tom"
def eat(self):
print("%s爱吃鱼"%self.name)
#使用类名()创建对象的时候,会自动调用初始化方法__init__
tom=Cat()
tom.eat()
改造初始化方法——初始化的同时设置初始值
在开发中,如果希望在创建对象的同时,就设置对象的属性,可以对`__init__`方法进行改造
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()
5.内置方法和属性
|序号|方法名|类型|作用|
|:---:|:---:|:---:|---|
|01|`__del__`|方法|对象被从内存中销毁前,会被自动调用|
|02|`__str__`|方法|返回对象的描述信息,`print`函数输出使用|
`__del__`方法
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关键字可以删除一个对象,代码没有执行完就已经删除了tom对象
del tom
print("-"*50)
`__str__`方法
注意:`__str__`方法必须返回一个字符串
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)
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("小明",75)
xiaoming.run()
xiaoming.eat()
xiaoming.eat()
print(xiaoming)
小明爱跑步扩展——小美也爱跑步
需求
提示
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)
xiaoming.run()
xiaoming.eat()
xiaoming.eat()
print(xiaoming)
xiaomei=Person("小美",60)
xiaomei.run()
xiaomei.eat()
xiaomei.eat()
print(xiaomei)
3.摆放家具
需求
剩余面积
class HouseItem:
def __init__(self,name,area):
"""
:paramname:家具名称
:paramarea:占地面积
"""
self.name=name
self.area=area
def __str__(self):
return"[%s]占地面积%.2f"%(self.name,self.area)
class House:
def __init__(self,house_type,area):
"""
:paramhouse_type:户型
:paramarea:总面积
"""
self.house_type=house_type
self.area=area
#剩余面积默认和总面积一致
self.free_area=area
#默认没有任何的家具
self.item_list=[]
def __str__(self):
#Python能够自动的将一对括号内部的代码连接在一起
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
#1.创建家具
bed=HouseItem("席梦思",4)
chest=HouseItem("衣柜",2)
table=HouseItem("餐桌",1.5)
print(bed)
print(chest)
print(table)
#2.创建房子对象
my_home=House("两室一厅",60)
my_home.add_item(bed)
my_home.add_item(chest)
my_home.add_item(table)
print(my_home)
注意
4.士兵突击
需求
class Gun:
def __init__(self,model):
#枪的型号
self.model=model
#子弹数量
self.bullet_count=0
def add_bullet(self,count):
self.bullet_count+=count
def shoot(self):
#判断是否还有子弹
if self.bullet_count<=0:
print("没有子弹了...")
return
#发射一颗子弹
self.bullet_count-=1
print("%s发射子弹[%d]"%(self.model,self.bullet_count))
class Soldier:
def __init__(self,name):
#姓名
self.name=name
#枪,士兵初始没有枪None关键字表示什么都没有
self.gun=None
def fire(self):
#1.判断士兵是否有枪
if self.gun is None:
print("[%s]还没有枪..."%self.name)
return
#2.高喊口号
print("冲啊...[%s]"%self.name)
#3.让枪装填子弹
self.gun.add_bullet(50)
#4.让枪发射子弹
self.gun.shoot()
#创建枪对象
ak47=Gun("ak47")
person=Soldier("许三多")
person.fire()
person.gun=ak47
person.fire()
注意:一个对象的属性可以是另外一个类创建的对象
应用场景
定义方式
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()
伪私有属性和私有方法
`Python`中,并没有真正意义的私有
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()
面向对象三大特性
1.继承的概念:子类拥有父类的所有方法和属性
2.语法:
class 类名(父类名):
pass
3.继承的传递性
4.方法的重写
1)覆盖父类的方法
2)对父类方法进行扩展
调用父类方法的另外一种方式
父类名.方法(self)
注意:如果使用当前子类名调用方法,会形成递归调用,出现死循环
5.父类的私有属性和私有方法
1.概念
2.语法
class 子类名(父类名1,父类名2...)
pass
3.问题
如果不同的父类中存在同名的方法,子类对象在调用方法时,会调用哪一个父类中的方法呢?
Python中的MRO——方法搜索顺序
4.新式类与旧式(经典)类
class 类名(object):
pass
多态案例演练
需求
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.game()
wangcai=XiaoTianDog("飞天旺财")
wangcai.game()
#2.创建一个小明对象
xiaoming=Person("小明")
#3.让小明调用和狗玩的方法
xiaoming.game_with_dog(wangcai)
1.实例
每一个对象都有自己独立的内存空间,保存各自不同的属性
多个对象的方法,在内存中只有一份,在调用方法时,需要把对象的引用传递到方法内部
在程序运行时,类同样会被加载到内存
2.在`Python`中,类是一个特殊的对象——类对象
概念和使用
示例需求
class Tool(object):
#使用赋值语句,定义类属性,记录创建工具对象的总数
count=0
def __init__(self,name):
self.name=name
#针对类属性做一个计数+1
Tool.count+=1
#创建工具对象
tool1=Tool("斧头")
tool2=Tool("榔头")
tool3=Tool("铁锹")
#知道使用Tool类到底创建了多少个对象?
print("现在创建了%d个工具"%Tool.count)
属性的获取机制
在`Python`中属性的获取存在一个向上查找机制
要访问类属性有两种方式:
注意:如果使用`对象.类属性=值`赋值语句,只会给对象添加一个属性,而不会影响到类属性的值
1.类方法
语法如下
@classmethod
def 类方法名(cls):
pass
示例需求
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("榔头")
tool3=Tool("铁锹")
Tool.show_tool_count()
2.静态方法
语法如下
@staticmethod
def 静态方法名():
pass
静态方法需要用修饰器`@staticmethod`来标识,告诉解释器这是一个静态方法
通过类名.调用静态方法
class Dog(object):
#狗对象计数
dog_count=0
@staticmethod
def run():
#不需要访问实例属性也不需要访问类属性的方法
print("狗在跑...")
def __init__(self,name):
self.name=name
Dog.run()
3.方法综合案例
需求
class Game(object):
#游戏最高分,类属性
top_score=0
@staticmethod
def show_help():
print("帮助信息:让僵尸走进房间")
@classmethod
def show_top_score(cls):
print("游戏最高分是%d"%cls.top_score)
def __init__(self,player_name):
self.player_name=player_name
def start_game(self):
print("[%s]开始游戏..."%self.player_name)
#使用类名.修改历史最高分
Game.top_score=999
#1.查看游戏帮助
Game.show_help()
#2.查看游戏最高分
Game.show_top_score()
#3.创建游戏对象,开始游戏
game=Game("小明")
game.start_game()
#4.游戏结束,查看游戏最高分
Game.show_top_score()
设计模式
单例设计模式
单例设计模式的应用场景
重写`__new__`方法的代码非常固定!
class MusicPlayer(object):
def __new__(cls,*args,**kwargs):
print("创建对象,分配空间")
#如果不返回任何结果,
return super().__new__(cls)
def __init__(self):
print("初始化音乐播放对象")
player=MusicPlayer()
print(player)
单例——让类创建的对象,在系统中只有唯一的一个实例
class MusicPlayer(object):
#定义类属性记录单例对象引用
instance=None
def __new__(cls,*args,**kwargs):
#1.判断类属性是否已经被赋值
if cls.instance is None:
cls.instance=super().__new__(cls)
#2.返回类属性的单例引用
return cls.instance
player1=MusicPlayer()
player2=MusicPlayer()
print(player1)
print(player2)
只执行一次初始化工作
class MusicPlayer(object):
#记录第一个被创建对象的引用
instance=None
#记录是否执行过初始化动作
init_flag=False
def __new__(cls,*args,**kwargs):
#1.判断类属性是否是空对象
if cls.instance is None:
#2.调用父类的方法,为第一个对象分配空间
cls.instance=super().__new__(cls)
#3.返回类属性保存的对象引用
return cls.instance
def __init__(self):
if not MusicPlayer.init_flag:
print("初始化音乐播放器")
MusicPlayer.init_flag=True
#创建多个对象
player1=MusicPlayer()
print(player1)
player2=MusicPlayer()
print(player2)
程序在运行时,如果`Python解释器`遇到到一个错误,会停止程序的执行,并且提示一些错误信息,这就是异常
程序停止执行并且提示错误信息这个动作,我们通常称之为:抛出(raise)异常
程序开发时,很难将所有的特殊情况都处理的面面俱到,通过异常捕获可以针对突发事件做集中的处理,从而保证程序的稳定性和健壮性
1.简单的捕获异常语法
在程序开发中,如果对某些代码的执行不能确定是否正确,可以增加`try(尝试)`来捕获异常
捕获异常最简单的语法格式:
try:
尝试执行的代码
except:
出现错误的处理
简单异常捕获演练——要求用户输入整数
try:
#提示用户输入一个数字
num=int(input("请输入数字:"))
print(num)
except:
print("请输入正确的数字")
2.错误类型捕获
在程序执行时,可能会遇到不同类型的异常,并且需要针对不同类型的异常,做出不同的响应,这个时候,就需要捕获错误类型了
语法如下:
try:
#尝试执行的代码
pass
except 错误类型1:
#针对错误类型1,对应的代码处理
pass
except(错误类型2,错误类型3):
#针对错误类型2和3,对应的代码处理
pass
except Exception as result:
print("未知错误%s"%result)
当`Python`解释器抛出异常时,最后一行错误信息的第一个单词,就是错误类型
异常类型捕获演练——要求用户输入整数
需求
try:
num=int(input("请输入整数:"))
result=8/num
print(result)
except ValueError:
print("请输入正确的整数")
except ZeroDivisionError:
print("除0错误")
捕获未知错误
在开发时,要预判到所有可能出现的错误,还是有一定难度的
如果希望程序无论出现任何错误,都不会因为`Python`解释器抛出异常而被终止,可以再增加一个`except`
语法如下:
except Exception as result:
print("未知错误%s"%result)
3.异常捕获完整语法
在实际开发中,为了能够处理复杂的异常情况,完整的异常语法如下:
try:
#尝试执行的代码
pass
except 错误类型1:
#针对错误类型1,对应的代码处理
pass
except 错误类型2:
#针对错误类型2,对应的代码处理
pass
except(错误类型3,错误类型4):
#针对错误类型3和4,对应的代码处理
pass
except Exception as result:
#打印错误信息
print(result)
else:
#没有异常才会执行的代码
pass
finally:
#无论是否有异常,都会执行的代码
print("无论是否有异常,都会执行的代码")
实例
try:
num=int(input("请输入整数:"))
result=8/num
print(result)
except ValueError:
print("请输入正确的整数")
except ZeroDivisionError:
print("除0错误")
except Exception as result:
print("未知错误%s"%result)
else:
print("正常执行")
finally:
print("执行完成,但是不保证正确")
异常的传递——当函数/方法执行出现异常,会将异常传递给函数/方法的调用一方
如果传递到主程序,仍然没有异常处理,程序才会被终止
提示
需求
def demo1():
return int(input("请输入一个整数:"))
def demo2():
return demo1()
try:
print(demo2())
except ValueError:
print("请输入正确的整数")
except Exception as result:
print("未知错误%s"%result)
1.应用场景
示例
提示用户输入密码,如果长度少于8,抛出异常
注意
2.抛出异常
需求
def input_password():
#1.提示用户输入密码
pwd=input("请输入密码:")
#2.判断密码长度,如果长度>=8,返回用户输入的密码
if len(pwd)>=8:
return pwd
#3.密码长度不够,需要抛出异常
#1>创建异常对象-使用异常的错误信息字符串作为参数
ex=Exception("密码长度不够")
#2>抛出异常对象
raise ex
try:
user_pwd=input_password()
print(user_pwd)
except Exception as result:
print("发现错误:%s"%result)
1.模块的概念
模块是Python程序架构的一个核心概念
2.模块的两种导入方式
1)import导入
import 模块名1,模块名2
提示:在导入模块时,每个导入应该独占一行
import 模块名1
import 模块名2
导入之后
使用`as`指定模块的别名
import 模块名1 as 模块别名
注意:模块别名应该符合大驼峰命名法
2)from...import导入
#从模块导入某一个工具
from 模块名1 import 工具名
#从模块导入所有工具,这种方式不推荐使用,因为函数重名并没有任何的提示,出现问题不好排查
from 模块名1 import *
导入之后
注意
3.模块的搜索顺序
`Python`的解释器在导入模块时,会:
在开发时,给文件起名,不要和系统的模块文件重名
示例
import random
#生成一个0~10的数字
rand=random.randint(0,10)
print(rand)
print(random.__file__)
注意:如果当前目录下,存在一个`random.py`的文件,程序就无法正常执行了!
这个时候,`Python`的解释器会加载当前目录下的`random.py`而不会加载系统的`random`模块
4.原则——每一个文件都应该是可以被导入的
实际开发场景
`__name__`属性可以做到,测试模块的代码只在测试情况下被运行,而在被导入时不会被执行!
在很多`Python`文件中都会看到以下格式的代码:
#导入模块
#定义全局变量
#定义类
#定义函数
#在代码的最下方
def main():
#...
pass
#根据__name__判断是否执行下方代码
if __name__=="__main__":
main()
概念
好处
案例演练
`__init__.py`
#从当前目录导入模块列表
from . import send_message
from . import receive_message
如果希望自己开发的模块,分享给其他人,可以按照以下步骤操作
1.制作发布压缩包步骤
1)创建setup.py
from distutils.core import setup
setup(name="hm_message",#包名
version="1.0",#版本
description="itheima's发送和接收消息模块",#描述信息
long_description="完整的发送和接收消息模块",#完整描述信息
author="itheima",#作者
author_email="[email protected]",#作者邮箱
url="www.itheima.com",#主页
py_modules=["hm_message.send_message",
"hm_message.receive_message"])
2)构建模块
python3 setup.py build
3)生成发布压缩包
python3 setup.py sdist
注意:要制作哪个版本的模块,就使用哪个版本的解释器执行!
2.安装模块
tar-zxvf hm_message-1.0.tar.gz
sudo python3 setup.py install
卸载模块
cd /usr/local/lib/python3/dist-packages/
sudo rm-r hm_message
3.`pip`安装第三方模块
#将模块安装/卸载到Python3.x环境
sudo pip3 install pygame
sudo pip3 uninstall pygame
#在`Linux`下安装`iPython3`
sudo apt install ipython3
1.文件的概念和作用
2.文件的作用
3.文件的存储方式
在计算机中,文件是以二进制的方式保存在磁盘上的
文本文件
二进制文件
1.在计算机中要操作文件的套路非常固定,一共包含三个步骤:
2.操作文件的函数/方法
|序号|函数/方法|说明|
|---|---|---|
|01|open|打开文件,并且返回文件操作对象|
|02|read|将文件内容读取到内存|
|03|write|将指定内容写入文件|
|04|close|关闭文件|
`open`函数负责打开文件,并且返回文件对象
`read`/`write`/`close`三个方法都需要通过文件对象来调用
3.read方法——读取文件
注意:`read`方法执行后,会把文件指针移动到文件的末尾
#1.打开-文件名需要注意大小写
file=open("123.txt")
#2.读取
text=file.read()
print(text)
#3.关闭
file.close()
文件指针
4.打开文件的方式
`open`函数默认以只读方式打开文件,并且返回文件对象
f=open("文件名","访问方式")
|访问方式|说明|
|:---:|---|
|r|以只读方式打开文件。文件的指针将会放在文件的开头,这是默认模式。如果文件不存在,抛出异常|
|w|以只写方式打开文件。如果文件存在会被覆盖。如果文件不存在,创建新文件|
|a|以追加方式打开文件。如果该文件已存在,文件指针将会放在文件的结尾。如果文件不存在,创建新文件进行写入|
|r+|以读写方式打开文件。文件的指针将会放在文件的开头。如果文件不存在,抛出异常|
|w+|以读写方式打开文件。如果文件存在会被覆盖。如果文件不存在,创建新文件|
|a+|以读写方式打开文件。如果该文件已存在,文件指针将会放在文件的结尾。如果文件不存在,创建新文件进行写入|
提示:频繁的移动文件指针,会影响文件的读写效率,开发中更多的时候会以只读、只写的方式来操作文件
5.按行读取文件内容
`read`方法默认会把文件的所有内容一次性读取到内存
如果文件太大,对内存的占用会非常严重
`readline`方法可以一次读取一行内容
方法执行后,会把文件指针移动到下一行,准备再次读取
#打开文件
file=open("123.txt")
while True:
#读取一行内容
text=file.readline()
#判断是否读到内容
if not text:
break
#每读取一行的末尾已经有了一个`\n`
print(text,end="\n")
#关闭文件
file.close()
6.文件读写案例——复制文件
目标
小文件复制
#1.打开文件
file_read=open("123.txt")
file_write=open("123.txt[复件]","w")
#2.读取并写入文件
text=file_read.read()
file_write.write(text)
#3.关闭文件
file_read.close()
file_write.close()
大文件复制
#1.打开文件
file_read=open("123.txt")
file_write=open("123.txt[复件]","w")
#2.读取并写入文件
while True:
#每次读取一行
text=file_read.readline()
#判断是否读取到内容
if not text:
break
file_write.write(text)
#3.关闭文件
file_read.close()
file_write.close()
文件操作
|序号|方法名|说明|示例|
|---|---|---|---|
|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(文件路径)`|
提示:文件或者目录操作都支持相对路径和绝对路径
1.文本文件存储的内容是基于字符编码的文件,常见的编码有`ASCII`编码,`UNICODE`编码等
`ASCII`编码
`UTF-8`编码格式
2.Ptyhon2.x中如何使用中文
# *-* coding:utf8 *-*
也可以使用
#coding=utf8
unicode字符串
# *-* 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))
在开发时千万不要使用 `eval` 直接转换 `input` 的结果,以下命令是非常危险的
__import__('os').system('rmdir(目录名)')