python基础

Python安装

官方网址自行下载https://www.python.org/

以3.7.0-amd64位版本为案例安装,双击运行安装包

image-20200526233405696

单击Install Now

image-20200526233405696

想要更改目录的自行更改

image-20200526233405696

successful表示安装成功

image-20200526233405696

运行输入cmd打开命令窗口(不清楚可以去cmd基础

找不到python环境解决方法

  • 手动添加到环境变量

    我的电脑右键属性

    image-20200526233405696

    高级系统设置

    image-20200526233405696

    环境变量

    image-20200526233405696

    双击path

    image-20200526233405696

    新建

    image-20200526233405696

    输入安装的路径

    image-20200526233405696

    保存好后退出重新打开cmd输入python

    image-20200526233405696

    可以看到上图中python已经启动成功

  • bat脚本安排环境变量

基本输入输出

1
2
3
4
5
6
print('我:"hello python"')
print("""python: "起开" """)

>>>
我:"hello python"
python: "起开"
  • print输出,输出字符串需要加上引号(单引号双引号都行)输出内容需要双引号则第一句使用单引号,第二句用三引号代表里面的内容全部是字符串。

python的注释

  • 注释在编程中是必不可少的部分,因为当你写完代码后隔几天就基本忘记了,而注释是帮助你了解代码的手段。而且注释还可以让你的代码更加通俗,当别人看到是也更容易理解。
1
2
3
4
5
6
7
8
#这是第一个注释
print ("hello hello")
"""这是一个多行注释
这是一个多行注释
这是一个多行注释
"""
#这是第二个注释
print("hello world") #输出欢迎信息
  • 开头一句是单行注释,所以在编译器中只能注释一行,按下空格键后将不会注释。三个双引号是多行注释可以大量写注释。

Python的计算

  • 在python中计算和普通的计算很相似,上过小学都会利用python的计算,

  • 普通加减乘除:代码如下

1
2
3
4
5
6
#定义苹果地单价
price=8.5
weigh=7.5
money=weigh*price
money=money-5
print(money)
  • 这段代码相信大家很容易看懂,单纯的赋值计算,在这里说一下print没有加引号,是因为要输出的是数字而不是字符串。

高级计算

  • 次方 ** 取余%

  • 例:

1
2
3
4
a=10**10 #表示10的10次方 a得到10000000000
print(a)
b=10%3 #表示10除以3 b得到1
print(b)
  • 在python中运算速度取决于你的电脑

人生苦短,我用python「2」

python的数据类型

  • Python3 支持 int、float、bool、complex(复数)。 和其他语言不同的是它没有长短之分,不会出现长整型之类的数据,大大简化了学习。

人生苦短,我用python「3」

  • 内置的 type() 函数可以用来查询变量所指的对象类型。还有一种判断是isinstance不经常用。
1
2
3
4
a, b, c, d = 20, 5.5, True, 4+3j 
print(type(a), type(b), type(c), type(d))

#输出 <class 'int'> <class 'float'> <class 'bool'> <class 'complex'>
  • 上述定义方法也是python支持的,在一行定义多个变量。输出的是类型,学到后面可以综合用户输入来判断输入内容的类型。

print

  • print是一个最基础的输出语句,虽然基础但是用法也很多。
1
2
3
4
str="I love python"
print(str*100) #将str的内容输出100遍
print(str[2]) #从第二个l开始输出
print(str[1:-2]) #输出love pyth 从1到-2的位置
  • python中是从0开始计数的,要注意改变一般数数的习惯

input

  • 输入指令,提示用户输入,通常设置一个变量接收。
1
2
str=input("你想对我说:"#注意这里输入的都是字符类型
str=int(input("你想对我说:") #这段代码将字符转化成整型
  • 转化后不能输入字符串,不然会报错

格式化字符

格式化字符主要是将输出内容变地更加灵活,格式化字符的种类和字符类型差不多。都是采用一个%跟一个字符。常用的就两个分别是%f和%s。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#格式化输出目的是让字符与数字一起输出%(d f s %)
#输出名字
name = "小明"
print ("我的名字是%s,请多多关照"%name)
#输出学号,09d的含义是不足9位前面用0补充
student_no = 1
print("我的学号是%09d"%student_no)
#输出小数 .2表示保留小数点几位
price = 8.0
weight = 5.1
money = price * weight
print("重量是%.2f kg,单价是%.2f 元/kg,一共%.2f 元"%(weight,price,money))
#输出%的数
scale = 50
print("输出:%.2f%%"%scale)
print("输出:%.2f%%"%(scale*10)) #数目乘10
print("输出:%.2f%%"%scale*10) #数量乘10

人生苦短,我用python「4」

源码

人生苦短,我用python「4」

输出

简单理解就是格式化字符是一个介质根据等量关系传入一句话中,使输出更加多样。

一个语句中有多个格式化字符在调用的部分需要加括号,括号表示元组(下一节会讲)。

1
2
3
4
5
str = "python is a program"
print("{str} is right".format(str=str))

>>>
python is a program is right

format不仅可以格式化字符串还可以格式化列表字典等数据

1
2
3
4
5
li = ["python","is","easy"]
print("{li[0]} {li[1]} {li[2]} right?".format(li=li))

>>>
python is easy right?
1
2
3
4
5
dic = {"name":"python","easy":"True"}
print("{name} {easy} right?".format(**dic))

>>>
python True right?

格式化类

格式化类表示类的返回值只用格式化。

1
2
3
4
5
6
7
8
9
10
11
12
class form():
def __init__(self,name,age):
self.name=name
self.age=age
def sum(self):
return "{name} are {age} years old".format(name=self.name,age=self.age)

Bl=form("Blosslom",20)
print(Bl.sum())

>>>
Blosslom are 20 years old

返回的字符串是使用到了格式化字符串。

r开头

以r开头表示后面的全部是字符串。

1
2
3
4
5
6
7
print(r"python is \n easy")
print("python is \n easy")

>>>
python is \n easy
python is
easy

f开头

以f开头相format

1
2
3
4
5
dic = {"name":"python","easy":"True"}
print(f"{dic['name']} {dic['easy']} right?")

>>>
python True right?

拓展*(只需了解)

交互式编程

我们可以在命令提示符中输入"Python"命令来启动 Python 解释器:

$ python3

执行以上命令后,出现如下窗口信息:

1
$ python3 Python 3.4.0 (default, Apr 11 2014, 13:05:11) [GCC 4.8.2] on linux Type "help", "copyright", "credits" or "license" for more information. >>>

在 python 提示符中输入以下语句,然后按回车键查看运行效果:

1
print ("Hello, Python!");

以上命令执行结果如下:

1
Hello, Python!

当键入一个多行结构时,续行是必须的。我们可以看下如下 if 语句:

1
>>> flag = True >>> if flag : ... print("flag 条件为 True!")

… flag 条件为 True!

脚本式编程

将如下代码拷贝至 hello.py 文件中:

1
print ("Hello, Python!");

通过以下命令执行该脚本:

python3 hello.py

输出结果为:

1
Hello, Python!

在 Linux/Unix 系统中,你可以在脚本顶部添加以下命令让 Python 脚本可以像 SHELL 脚本一样

可直接执行:

#! /usr/bin/env python3

然后修改脚本权限,使其有执行权限,命令如下:

1
$ chmod +x hello.py

执行以下命令:

1
./hello.py

输出结果为:

1
Hello, Python!

if判断语句

在python中if条件语句非常简单,语法【if 条件:】注意冒号非常重要不仅if语句几乎所有的带条件的语句都需要在最后加上冒号。

1
2
3
4
5
6
7
8
# 输入一个年龄(ctrl+/表示注释)这是注释的快捷键
age = float(input("请输入年龄:"))
#对年龄判断
if age >=18:
print("你可以进网吧嗨皮")
print("欢迎")
else:
print("go out!")

在使用该语句是可以只用if,如果不能满足需求可以在后面加elif 语法一样,缩进要一致。最后除了以上条件结尾用else结尾,语法也一样。

1
2
3
4
5
6
if 条件:
要执行的内容
elif 条件:#可有可无
要执行的内容
else#可有可无
要执行的内容

逻辑运算

  • and:两个条件同时为真时结果为真

  • or:两个结果只要有一个满足就为真

  • not:条件为真结果就是假

注意这里非常容易混淆这两个运算中结果只有两种真(1)假(0)在结合if判断时真是执行下面的操作,假则不执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#判断年龄在0-120之间
age = float(input("请输入你的年龄:"))
# 要求age>=0 同时要满足age<=120
if age>=0 and age<=120:
print("你的年龄是正确的")
else:
print("你在骗我")
# 定义成绩
math_score=float(input("请输入数学成绩:"))
PE_score=float(input("请输入体育成绩:"))
chinese_score=float(input("请输入语文成绩:"))
# 用逻辑判断只要一门超过90分就算合格
if math_score>=90 or PE_score>=90 or chinese_score>=90:
print("你非常liha")
else:
print("菜鸡快加油")

人生苦短,我用python「5」

1
2
3
4
5
6
#赋予布尔值
are_sb=False
# 判断是否满足条件
# not是用在不满足时用的
if not are_sb:
print("你不是,不准入内")

列表

  • List(列表) 是 Python 中使用最频繁的数据类型。
  • 列表可以完成大多数集合类的数据结构实现。列表中元素的类型可以不相同,它支持数字,字
  • 符串甚至可以包含列表(所谓嵌套)。
  • 列表是写在方括号 [] 之间、用逗号分隔开的元素列表。
  • 和字符串一样,列表同样可以被索引和截取,列表被截取后返回一个包含所需元素的新列表。
1
2
list=[52,"python",1314]
print(list[0:1]) #输出:52 python

在列中的输出形式是以逗号间隔为单位的。

元组

元组(tuple)与列表类似,不同之处在于元组的元素不能修改。元组写在小括号 () 里,元素

之间用逗号隔开。

元组中的元素类型也可以不相同:

字典

字典(dictionary)是Python 中另一个非常有用的内置数据类型。

列表是有序的对象集合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通

过键来存取的,而不是通过偏移存取。

字典是一种映射类型,字典用"{ }"标识,它是一个无序的键(key) : 值(value)对集合。

键(key)必须使用不可变类型。

在同一个字典中,键(key)必须是唯一的。

1
2
dic={"name":"小明","age":18}
print(dic["name"]) #输出小明

字典通过键检索

循环

语法于if相似

1
2
while 条件:
执行代码

人生苦短,我用python「6」

1
2
3
4
5
6
7
8
9
10
#定义计数
i = 0
# 进行循环
while i<10:
#中途满足条件break退出
if i == 3:
break
print(i)
i+=1
print("over")

这个代码输出:0 1 2

break是直接跳出循环只能输出之前执行的代码。

1
2
3
4
5
6
7
8
9
10
i=0
while i<10:
i+=1
# continue当满足时直接跳转到while,在这之前一定要将计数器+1
# 错误例子 if i ==3 or 5 这里指i == 3 先判断这个是否为真(不是3就是假)or后 再判断5是否为真
# 因为5不是0永远为真 所以if永远成立
if i == 3 or i == 5:
continue
print(i)
print("over")

continue表示不执行下面代码跳到while开头重新执行。

实战

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#定义计数器及变量
N = float(input("请输入所需乘法表行数:"))
row = 1
#进入循环
while row <= N:
# 定义列数
lin = 1
#进入循环
while lin<=row:
answer=lin*row
# print("%d*%d=%d"%(row,lin,row*lin),end=" ")
print("%d*%d=%d"%(lin,row,answer),end="\t")# 转义字符\t 制表符是让字符在垂直方向上对齐
lin+=1
row+=1
print("")

人生苦短,我用python「7」

以上是列出九九乘法表,当然如果你想更多,只要你的计算机好,尽管算。

人生苦短,我用python「7」

转义字符

1
2
3
4
5
# 转义字符\t 是让字符在垂直方向上对齐
print("1\t2\t3")
print("10\t20\t30")
# \n换行符 \"输出双引号
print(" hello\n\"python")

源码说明一切,这两种是最常用的转义字符,其余的要慢慢积累。

函数

从这里开始就进入了python的关键部分了。

函数是什么,高中就已经解释过函数的意义了,在程序中一样,函数具有一一对应的关系,我们可以自己定义函数,定义的函数就像一个个的小包,想用时只要调用自己定义的函数名。

python中函数用def关键字定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def a():
#定义计数器及变量
N = float(input("请输入所需乘法表行数:"))
row = 1
#进入循环
while row <= N:
# 定义列数
lin = 1
#进入循环
while lin<=row:
answer=lin*row
# print("%d*%d=%d"%(row,lin,row*lin),end=" ")
print("%d*%d=%d"%(lin,row,answer),end="\t")# 转义字符\t 制表符是让字符在垂直方向上对齐
lin+=1
row+=1
print("")

就看第一行代码def关键字后面是函数名,自己定义的函数名,括号是什么意思呢?括号是为了输入参数的,这段代码中内置了输入,所以不需要输入参数,但是括号必须有。定义好这个函数后就可以直接用了。在一个文件中调用时只需输入函数名即可。

人生苦短,我用python「8」

看最后一行这是调用函数。如果在不同文件中要怎样调用呢?

人生苦短,我用python「8」

这是两个不同的py文件

1
2
import bl_01_乘法表函数
bl_01_乘法表函数.a()

另一个文件的源码import是导入模块就等于导入文件,调用函数【模块名.函数名】这种操作还是很简单的。

函数有什么作用呢?首先大量重复的代码你只需要写一遍,用到就调用。然后你可以形成一个库,后面编写只需框架和调用函数,简化了编写。第二就是你可以用别人编写的函数,在网上下载大神分享的库,瞬间让你变成高手。

函数2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 定义一个函数表示已经将函数封装
# 如果不去调用函数,函数是不会执行的
def hello_four():
"""say hello"""
def hello_three():
def hello_two():
def hello():
print("hello",end="")
print("hello")
print("hello")
hello()
hello()
hello_two()
hello_two()
hello_three()
hello_three()
hello_four()
hello_four()

看的懂这串代码如果看的懂函数的定义基本已经没问题,大致意思就是函数中定义函数,函数中调用函数。

函数的参数

函数的参数在这里就是一个桥梁,函数就等于一个小岛,小岛需要物资,这个运输途径就是参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
# 定义一个函数
# 括号中的数是形参
def sum_two(sum1,sum2):
"""两个数相加"""
# 这是一个函数注释
answer = sum1+sum2
print("%f+%f=%f"%(sum1,sum2,answer))
# sum1=input("请输入第一个数:")
# sum2=input("请输入第二个数:") 此为错误输出 输入1 and 1 输出11因为是字符串
sum1=float(input("请输入第一个数:"))
sum2=float(input("请输入第二个数:"))
# 调用时括号中的数是实参
sum_two(sum1,sum2)

在这里最后一行的调用的代码里括号传入的就是物资,在这里叫实参,函数定义的东西叫虚参

两个参数的传输遵循的是顺序而不是定义的变量,实参数可以将名称改变,它仅仅和外部相对应,同理虚参只和内部对应他们遵循的传输是顺序

人生苦短,我用python「9」

函数与模块

函数与模块是什么关系呢?学过编程的都知道,模块包含函数通俗地讲就是模块大于函数。在python中函数都被封装在模块中,通常一个模块封装了很多个函数。

我们拿python的内置模块来讲解,python中有一个random模块,这个模块是让计算机生成随机数,调用模块的命令是import.模块名。调用模块后需要用到模块中的函数,同理 模块名.函数名 下面来看一段代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#提示玩家出拳
player = float(input("请输入石头(1) 布(2) 剪刀(3):"))
# 电脑输出 调用随机数
import random
computer = random.randint(1,3) #注意随机数语法
print("电脑出的%0.f 你出的%0.f "%(player,computer))
#判断输赢
if ((player==1 and computer==3)
or(player==2 and computer==1)
or(player==3 and computer==2)):
print("电脑你真菜")
elif player==computer:
print("平局")
else:
print("电脑你小心点")

代码中用到了random模块中的randint函数这个函数的意思是输出随机的整数,整段代码就是一些简单的if判断语句组合。看过前面文章的读者应该很容易理解。函数和模块的应用可以非常灵活,基础打好后可以慢慢探索。

1
2
3
4
5
6
7
8
9
10
11
def mut(b):
count=0
while count<b:
count+=1
print("%d*%d=%d"%(count,b,count*b),end=" \t")
terget=int(input())
count=0
while count<terget:
count+=1
mut(count)
print("")

这段代码没有注释,它的执行效果和前面的乘法表是一样的。

人生苦短,我用python「10」

它们有什么区别呢?区别就是算法不一样,程序的精巧之处就在这里,你可以用很多种方法实现同一个目标。

列表的基本使用

这一节开始需要背的内容就变多了。

通过代码来解释,一下的方法都是默认全局变量。

人生苦短,我用python「11」

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 定义列表
name_list=["holle","you","shit"]
# 调用列表
# list index out of range列表超出索引因为计数从0开始列表中没有四个字符串
print(name_list[0:3])
# 取索引知道名字搜索位置
# 使用index时如果内容不在列表中会报错
print(name_list.index("shit"))
# 修改,将you修改
name_list[1]="草泥"
# 追加
# append 可以向列表末尾追加数据
name_list.append("mina")
# insert 在指定的位置加数据
name_list.insert(1,"nitema")
# extend 在列表中追加另一个列表
number_list=[54188,520,1314]
name_list.extend(number_list)
# 清除删除
# remove 删除指定的数据
name_list.remove("草泥")
#删除最后一个数据
name_list.pop()
# 删除第三个数据
name_list.pop(2)
# 清空列表
name_list.clear()
print(name_list)

在这里特别要注意的是计算机是从0开始数的

1
2
3
4
5
# 定义数据
name_list=["sb","2b","s2b"]
# del删除数据
del name_list[1]
print(name_list)

del也是删除数据但是并不常用

列表统计

1
2
3
4
5
6
7
8
9
10
# 定义列
name_list=["张三","里斯","王武","张三"]
# len(length)用来查看列表的数据个数 注意用法
name_list_len=len(name_list)
print("名列表中有 %d 个名字"% name_list_len)
# count查看列表中数据有多少个
count=name_list.count("张三")
print("列表中有 %d 个张三"% count)
name_list.remove("张三")
print(name_list)

len的用处特别多在以后的编写中常常用来判断列表中是否存在数据。

列表排序

列表里的数据是按照用户输入时排序的,如果想要按照升序,降序等排序就要使用它的内置函数了。中文排序规则为按照开头字母的顺序。

sort这个属性是排序如果不加任何参数默认升序,加上reverse=Ture这个参数按照降序。reverse这个属性是反转。

1
2
3
4
5
6
7
8
9
10
11
12
13
name_list=["f","b","c","d"]
number_list=[7,21,5,9,11]
# 升序 默认是false
name_list.sort()
number_list.sort()
# 降序 reverse翻转=True(t要大写)
name_list.sort(reverse=True)
number_list.sort(reverse=True)
# 反转
name_list.reverse()
number_list.reverse()
print(name_list)
print(number_list)

字典基本操作

1
2
3
4
5
6
7
8
9
10
11
12
13
# 分为key和值 中间要用:分开
info={"name":"sb",
"age":19,
"like":"eat",
"sex":"man"}
# 如果不存在将在后面加一个
# 增加修改
info["thing"]="people"
# 如果存在修改数据
info["name"]="2b"
# 删除
info.pop("name")
print(info["name"])

人生苦短,我用python「12」

1
2
3
4
5
6
7
8
9
10
11
12
info={"name":"小宁",
"age":18}
# 和列表一样len
print(len(info))
# 合并字典
info_2={"weight":55,
"age":20}
# 注意实用update如果键值重复将进行覆盖
info.update(info_2)
# 清空
info.clear()
print(info)

字典的操作和列表的很相似,元组没有操作因为它是不可修改的。

遍历

遍历非常类似于循环,但是它弥补了循环的不足。遍历可以将一个列,元组或字典当作条件。将所有情况执行一遍。基本用法如下。

人生苦短,我用python「13」

1
2
3
4
5
6
rep_dic={"name":"小明",
"qq":1111,
"phone":110}
# k是遍历的关键字
for k in rep_dic:
print("%s---%s"%(k,rep_dic[k]))#输出key 和 key保留的值

代码中的关键部分是 for k in rep_dic: 这句话的意思是将字典中是每一个值都当作一个条件传入k,每次取一个进行循环,直到取完字典中的所有值 。记住在这里值是代表的key ,它遍历的是key而不是key保留的数值。

1
2
3
4
5
6
7
8
9
10
con_liset=[
{"name":"张三",
"qq":123,
"phone":110},
{"name":"里斯",
"qq":321,
"phone":10010}
]
for con_get in con_liset:
print(con_get["name"])

这串代码是遍历列,列中的每一给元素都是一个字典,所以会将字典传入con_get,在内部就可以单独对每一个字典进行操作。注意他不会遍历字典,要想遍历字典还需嵌套一个for。

遍历字符串

1
2
3
4
5
6
str1="my name is blosslom"
str='我的名字叫Blosslom'
for char in str:
print(char)
for char in str1:
print(char)

将会一个字符一个字符地输出

字符串的统计操作

主要用到len和count

1
2
3
4
5
str="hello niho hello"
print("里面有%d个字符"%len(str))
char=input("请输入要统计的字母:")
print("里面有字母%s %d个"%(char,str.count(char)))
print(str.index("h")

len将字符串中的内容数量统计成数字传递出去,count将字符串中一样的字符出现的次数传递出去。

拓展

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
str=" \t"
print(str.isspace())
# 判断是否只包含数字
# 这三种方法都不能判断小数
num_str="1"
print(num_str.isdecimal())
print(num_str.isdigit())
print(num_str.isnumeric())
# 判断是否以某一单词开头 结尾 字母位置
str_2="hello python"
print(str_2.startswith("hello"))
print(str_2.endswith("python"))
# find与index的区别是find不会报错
print(str_2.find("llo"))
# 替换 输出改后的字符串 不会修改字符串
print(str_2.replace("hello","hi"))

求质数实战

人生苦短,我用python「14」

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
count_1=2
print("2")
traget=int(input("请输入要求的范围:"))
# zhisu=[]
all=[]
# print(1,2,3,5,7,11,13,17,19)
while count_1<traget:
all.append(count_1)
count_1+=1
save_yushu=[]
for count_z in all:
yushu=count_1%count_z
save_yushu.append(yushu)
save_yushu.sort()
# for get_yushu in yushu:
if save_yushu[0]!=0:
print(count_1)

一短没有注释的代码,这段求质数的有效代码仅仅14行,这还不是最简的算法,此生无悔入python。

作为代码的原作者看着着一串串的也是很懵逼。对照代码从头讲解。

count_1=2 #定义初始的递增值

print(“2”) #这个是输出2 因为2是第一个质数这和第一行代码有联系从2开始定义就不会输出2了

traget=int(input(“请输入要求的范围:”)) #这个是你需要检测的范围

all=[] #定义空列表用来保留所有数

while count_1<traget: #进入循环

all.append(count_1) #在all列中添加计数,用来求质数

count_1+=1 #计数器递增

save_yushu=[] #定义空列 用来存储余数

for count_z in all: #进入for 遍历all列 目的是为了让这个数除以所有比他小的数

yushu=count_1%count_z #开始求余数

save_yushu.append(yushu) #将求出的余数储存到余数列

save_yushu.sort() #对余数进行递增排序

if save_yushu[0]!=0: #判断第一个余数是不为0?

print(count_1) #不为0是质数

人生苦短,我用python「14」

当然这种求质数的算法是最慢的(主要是了解用法)

查看地址内存

在pyhon中可以用id这个内置函数来查看数据存放的内存地址。

人生苦短,我用python「15」

1
2
3
4
5
6
7
8
9
10
11
12
def id_find(num_x):
print("数字%d的地址是%d"%(num_x,id(num_x)))
str="hello"
print("字符串的内存地址是%d"%id(str))
return str
# num_s引用数字的地址
num_s=1
print("数字%d的地址是%d"%(num_s,id(num_s)))
# 将保存的内存地址传递
# 用r来接收return返回的str
r=id_find(num_s)
print("%d"%id(r))

着串代码的输出结果为:

1
2
3
4
数字1的地址是140707080557600
数字1的地址是140707080557600
字符串的内存地址是2741824272904
2741824272904

可以明显看出不管是在函数内输出1的地址还是在函数内输出1他们的内存地址都是一样的。由此我们可以知道,python为1创建了一个空间用来保存1。当我们再次调用这个定义的1时不用再次创建,直接从地址中调用。以上内入不求深究,知道即可。

变量的生命周期

我们创建一个变量代表着它的出生,当它从内存地址中删除时也就代表着它的死亡。变量分为全局变量和局部变量。在整个程序框架和函数缩进一样的时全局变量,只有在程序结束或让它结束时它才消失。局部变量时定义在函数内的,一旦函数结束变量的内存也直接释放。所以全局变量可以供给所有,局部变量只为内部函数提供。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def demo():
# num出生:执行输出1
# num死亡:输出结束
num=1
print(num)
def demo2():
pass
# 另一个函数内也不能使用
# print(num)
# 函数内定义的变量是局部变量外部不能使用
# print(num)
demo()
# 全局变量
num=10
def demo3():
# 修改全局变量
num=2
# 函数不能修改全局变量num相当于局部变量
print(num)
def demo4():
print(num)
demo3()
demo4()

函数中定义全局变量

在python中,全局变量是不能用原始方法在函数中重新定义的,但是python中没有不可能,使用global 变量名 之后就可以改变这个全局变量了。

1
2
3
4
5
6
7
8
9
10
11
12
13
num=1
print(num)
def demo():
# 在函数中改变全局变量
global num
num=10
print(num)
def demo2():
print(num)
print(name)
demo()
demo2()
name=11

多个返回值

我们知道在函数中我们可以返回函数中的值,我们学的是返回一个值,但是往往函数中会产生多个值,代码如下。

人生苦短,我用python「16」

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def task():
num=1
num2=2
# 返回元组可以省略括号
# return (num,num2)
return num,num2
result=task()
# 拿到单个数
print("数一是%d"%result[0])
print("数二是%d"%result[1])
# 一般方法,必须意义对应
g_num,g_num2=task()
print(g_num)
print(g_num2)

在返回一行代码中有两个变量中间用逗号隔开,再来看外部接收的变量,其实它接收的是一个元组,要想单独获得还需要单独提取。

交换数字

每个编程语言中都有交换数字的功能,但是python最独特。我们定义两个变量a=1 b=2将两个数字的值进行交换。

1
2
3
4
5
6
a=1
b=2
# 方法一
a=a+b
b=a-b
a=a-b

这个换值的原理用小学的水平都能理解出来,但是这个对python来说太麻烦了。

1
a,b=(b,a)

这个就是python的方法,直接利用元组替换别人用3行代码,我python只用一行。

参数对全局变量操控

往往有时候我们需要在函数内部进行操作,变量定义在外部可是操作在内部,在内部操作中需要修改外部的变量,除了上次提到的global还有什么方法呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def task(num_x,num_list_x):
# 参数虽然是全局变量但是又被修改
num_x=1
print(num_x)
num_list_x=[1,2,3]
print(num_list_x)
num_s=2
num_list_s=[4,5,6]
# 实参调用全局变量到函数中
task(num_s,num_list_s)
# 如果不return不会输出局部变量
print(num_s,num_list_s)

#输出结果为
1
[1, 2, 3]
2 [4, 5, 6]

仔细看这段代码,虽然在函数中改变了变量,在函数输出中也变了,但是一到外部输出却总是原来定义的数,这就说明在函数中不能重新定义全局变量。再看下段代码。

人生苦短,我用python「17」

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def demo(num_list_x):
print("函数中输出")
# 使用方法添加9
num_list_x.append(9)
print(num_list_x)
g_num=[1,2,3]
demo(g_num)
print("外部输出")
#输出的和原定义的不一样,因为在函数中用方法改过了
print(g_num)

#输出结果为
函数中输出
[1, 2, 3, 9]
外部输出
[1, 2, 3, 9]

这段代码的输出就和更改过后的一样了,为什么呢?很明显我们没有重新定义变量,我们是用方法来更改变量的,所以由此推出用方法可以修改全局变量。

省略参数

前面我们知道,在为函数的参数赋值时每一个参数都要赋值,如果少一个程序都会报错,但是如果我们有时不需要给参数赋值要怎么办,这就需要我们用到省略参数了。看下面的代码。

人生苦短,我用python「18」

1
2
3
4
5
6
7
8
9
10
11
# 定义了省略参数,这个参数只能在结尾 title=""定义了一个缺省参数
def info(name,title="",gender=True):
gender_text="男生"
# if判断
if not gender:
gender_text="女生"
print("%s 是 %s"%(name,gender_text))
# 没有第二个参数,因为省略
info("小明")
# 前面有缺省参数时要指定参数
info("你妹",gender=False)

代码中有两个参数时省略参数,title="" ,gender=True 这两个省略参数有什么不同呢?第一给省略参数是你不赋值什么都没有,第二个事你不赋值默认为True 当然你还可以改为gender=1 不管你等于什么原理都一样。

多值参数

如果我们想要给一个参数传入多个值怎么办,这里就要用到多值参数了,代码如下

1
2
3
4
5
6
7
# 带一个*表示定义元组两个表示字典
def demo(num,*nums,**name):
print(num)
print(nums)
print(name)
# 字典实参同省略参数
demo(21,2,2,1,1,mane="小明",age="18")

参数前加一个是元组两个是字典所以你传入的东西就可以以多个值传入了,不同的用法在后面还会慢慢渗透。

多值参数的应用

我们学了多值参数,他有什么作用呢?随便举个例子,他可以做任意数的相加,看下面代码

1
2
3
4
5
6
7
def demo(*args):
num=0
for c in args:
num+=c
return num
result=demo(1,2,3,4,5,6,78,9)
print(result)

这段代码利用for遍历来将元组中的数逐一相加,最后输出结果。这又为累加提供了一种方法

拆包

拆包是什么意思呢?这还和多值参数有联系。如果我们定义好了元组或字典时我们输入实参时他会当作一个多值参数处理,这就很麻烦了。利用拆包就可以解决这个问题了。

人生苦短,我用python「19」

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def demo(*num,**info):
print(num)
print(info)
tir=(1,2,3)
dic_info={"name":"小明","age":"18"}
demo(tir,dic_info)
# 调用函数时也用*等于拆包
demo(*tir,**dic_info)
# 效果同上
demo(1,2,3,name="小明",age="18")

#输出:
((1, 2, 3), {'name': '小明', 'age': '18'})
{}
(1, 2, 3)
{'name': '小明', 'age': '18'}
(1, 2, 3)
{'name': '小明', 'age': '18'}

仔细对比我们可以发现第一个是一整个元组,第二个就分开了,第三个和第二个一样。这就是拆包的作用。

递归

递归的概念许多人都是第一次听,而且这个知识点相当的难,想要用到递归来编程,不仅要具备高超的技术,还要拥有清晰的逻辑思路。一般人能不用递归就不用递归,这个对技术要求相当高,而且它的递归层数只有998层。看代码实例。

1
2
3
4
5
6
7
8
9
def demo(num):
print(num)
# 递归出口
if num==1:
return num
# 自己调用自己
demo(num-1)
num=demo(10)
print(num)

递归纯属一个由语句组成的代码,用到了函数的调用,递归必须要设置出口,不然会直接报错,看下面这段累加的递归

人生苦短,我用python「20」

1
2
3
4
5
6
7
8
9
10
11
def sum_all(num):
# 设置出口
if num==1:
# 并且返回这个1 由result接收
return 1
# 经过if到这里 result接收1 这一层num=2
result=sum_all(num-1)
# 出来后执行再次返回,返回的是1+2 接着再到result=sum_all(num-1)这时的result是1+2再返回上一层....
return result+num
result=sum_all(998)
print(result)

这段代码可以帮助你理解递归,解释都在注释上,它就是一层一层的嵌套,嵌套了998层,也就可以做1到998的累加,难就难在他是以少量的代码完成大量的嵌套。

面向对象

在开始讲面向对象之前,先介绍一下面向对象,程序是有一个发展过程的,最原始的是机器语言,就是0和1这种语言是CPU可以直接看懂的语言,到后来计算机的专家们为了方便用一些英文来代表0和1,形成了汇编语言即使已经简化过的语言仍然只有专家能够熟练操作,还有一种数学语言在中间,到了第三阶段高级语言形成让计算机更加亲近与人,之前的高级语言是没有面向对象开发的,写出来的程序就是一个大文件,文件中用goto连接虽然这个方法简单但是写出的代码可以说自己都看不懂,知道面向对象出现为语言带来了一片新天地。

面向对象是一个大的概念,我们通过创建类再创建对象来实现,创建类需要用到class 类名

这个类名需要用到驼峰命名发,就是首字母大写。

1
2
3
4
5
6
7
8
9
10
11
12
13
# 类名要用驼峰命名发
class Cat:
def eat(self):
print("小猫要喝水")
def drink(self):
print("小猫要喝水")
tom=Cat()
tom.drink()
tom.eat()
print(tom)
iddr=id(tom)
# x表示十六进制的数
print("%x"%iddr)

可以看到代码中我们在一个类中创建了几个方法(函数),在面向对象中称为方法,创建完对类后我们需要创建对象,tom=Cat() tom.drink()注意这里我们的这个代码相当于Cat.drink(tom) 为什么呢?这个tom就是我们创建的对象就是self,比较难理解。

人生苦短,我用python「21」

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Cat:
def eat(self,name):
self.name=name
print("%s要吃鱼"%self.name)
def drink(self,name):
self.name=name
print("%s要喝水"%self.name)
self.eat("fuck")
# 创建猫对象
tom=Cat()
# 赋予属性
# tom.name="tom"
tom.drink("shit")
tom.eat("tom")
print(tom)
#创建第二个猫对象
lazy_cat=Cat()
# lazy_cat.name="蓝猫"
lazy_cat.eat("蓝猫")
lazy_cat.drink("蓝猫")
print(lazy_cat)

这段代码创建了两个对象慢慢理解基本上可以掌握这种编程思路。

初始化

在类中第一个方法应该写为初始化,初始化方法的作用就是创建对象后不用调用这个方法它就会自动执行,一般都是为了设置属性用的。在类中有着非常重要的作用。有一些方法是内置方法形式都和__init__()一样。

人生苦短,我用python「22」

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Cat:
# 下面没有调用,这个是自动调用,在这里定义就是默认的属性
def __init__(self,new_name):
print("这是一个初始化")
self.sht=new_name
def name(self):
self.sht="ss"
print("%s"%self.sht)
def age(self):
print("4")
print("%s"%self.sht)
# 进入第一层
tom=Cat("tom")
tom.age()
# print(tom.sht)
# 这是定义属性
# tom.shit="tom"
# 进入第二层
tom.name()
lazy_cat=Cat("lazy")
lazy_cat.name()

#代码输出:
这是一个初始化
4
tom
ss
这是一个初始化
ss

我们发现输出了两次“这是一初始化”并且代码中没有调用初始化方法,它是自动执行的,再看tom=Cat(“tom”)这是创建对象上一节也讲过实际上self就是左面的tom 那括号里的tom有事什么呢?这是第二两个参数它传入到初始化变量的new_name中。

_del_

此方法在类中的作用就是,当变量消失时,最后一次被调用,并且这个调用不需要专门调用。

人生苦短,我用python「23」

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Cat:
def __init__(self,name):
self.name=name
print("%scome"%self.name)
def two(self,name):
# 如果没有这给name输出的是初始定义的东西,定义之后再加上参数则修改了这个
self.name=name
print(self.name)
def __del__(self):
print("%s gone"%self.name)
tom=Cat("tom")
tom.two("tto")
print("-"*50)
# 结束时回收前再调用一次__del__

_str_

这个的用法是将输出变为字符串,因为一般对象输出都是得到的内存地址。

人生苦短,我用python「23」

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Cat:
def __init__(self,name,age):
self.name=name
self.age=age
print("%scome"%self.name)
def __del__(self):
print("%s gone"%self.name)
print("%s die"%self.age)
# 为属性赋予一个字符串
def __str__(self):
return "%s\n%s"%(self.name,self.age)
tom=Cat("tom","10")
print(tom)
print("-"*50)

面向对象实战

人生苦短,我用python「24」

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 函数名规定下滑线+h
class HouseItem:
def __init__(self,name,area):
# 前一个name是属性名,后一个是接受参数
self.name=name
self.area=area
def __str__(self):
return "%s占地%.2f平方米"%(self.name,self.area)
class House:
def __init__(self,house_shape,area):
self.house_shape=house_shape
self.area=area
# 剩余面积
self.stay_area=area
# 家具
self.house_list=[]
def __str__(self):
return ("户型[%s]\n总面积%.2f平方米[剩余面积%.2f平方米]\n家具%s"%(self.house_shape,self.area,self.stay_area,self.house_list))
# fr参数由下面的bed传过来,而bed又是调用的第一个类
def house_add(self,fr):
# 根据逻辑推导fr.area就是类一定义的self.name
# 利用这种方法可以调用类里面__init__定义的属性
if fr.area>self.stay_area:
print("%s太大"%fr.name)
return
self.house_list.append(fr.name)
self.stay_area-=fr.area
def house_min(self,fr):
if len(self.house_list)==0:
print("什么都没有")
return
self.house_list.append(fr)
self.area-=fr.area
print(fr.name)
print("已出具")
# 创建家具对象
bed=HouseItem("bed",4)
desk=HouseItem("desk",2)
sofa=HouseItem("sofa",4)
# 创建房子对象
my_home=House("四室两厅",160)
# 此语句调用了二类.后为二类里的函数括号里将一类以参数形式放入所调用的函数
my_home.house_add(bed)
my_home.house_min(bed)
my_home.house_min(bed)
# print(my_home)

简单介绍一下代码的作用,代码创建一个房子对象,并且创建家具对象,将家具添加到房子内,房子的面积会随着添加的家具而减小。 代码的基本解释都已经注释,能够独立阅读代码也是一种练习。

游戏型编程实战

废话不说,看代码。

人生苦短,我用python「25」

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class gun:
# 创建枪的型号子弹数量
def __init__(self,model):
self.model=model
self.bullet_number=0
def __str__(self):
return "你拿的枪是%s"%self.model
# 加子弹
def add_bullet_h(self,number):
self.bullet_number+=number
print("添加子弹%d"%number)
# 开枪
def shoot_h(self):
if self.bullet_number<=0:
print("没子弹了")
return
else:
self.bullet_number-=1
print("啪~~~剩余子弹%d"%self.bullet_number)
class sodier:
def __init__(self,name):
# 定义士兵名字
self.name=name
# 定义士兵武器
self.weapon=uzi
def fight_h(self):
# 使用is地址判断
if sd.weapon is None:
print("[%s]没枪打毛线" % sd)
return
# 装子弹
sd.weapon.add_bullet_h(50)
# 开枪
sd.weapon.shoot_h()
uzi=gun("uzi")
sd=sodier("xus")
print(uzi)
# xusanduo.weapon=uzi
sd.fight_h()
# print(xusanduo.weapon)

这段代码是我跟着老师一起写的,他的运行结果非常简单,结果如下:

1
2
3
你拿的枪是uzi
添加子弹50
啪~~~剩余子弹49

我们写了这么多行代码就输出三行,什么鬼,这有什么意义。所以很多人都无法成为大神,学习编程的前期是非常艰难的,因为你付出的和你得到的天差地别。

解释一下代码,枪类初始定义了型号,定义了装子弹开枪的方法。士兵类定义了名字,和战斗的方法,其中有判断是否拿枪,命令士兵装子弹。

初学者肯定会有疑惑,这是游戏吗?分明就是文字游戏。其实做游戏是另一门学问,py里有一个pygame模块是别人写好专门用来做游戏的模块,你可以将图像编入游戏中,反正没接触过的听着很复杂。慢慢学习一切知识点都会不期而遇。

继承

面像对象有一个特性就是继承,意思就是一个子类可以继承父类定义的方法,方法非常简单。

人生苦短,我用python「26」

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Animal:
def eat(self):
print("吃")
def drink(self):
print("喝")
def run(self):
print("跑")
def sleep(self):
print("睡")
def __only(self):
print("my")
# 在子类中继承父类
class dog(Animal):
def bark(self):
print("叫")
def eat(self):
print("eat shit")
# 继承的传递性,如果不能满足可以重编方法就同普通编写
class superdog(dog):
def fly(self):
print("飞")
def bark(self):
print("sb")
# 调用父类的方法
super().bark()
super().eat()
dog=superdog()
dog.bark()
dog.drink()
dog.eat()
dog.run()
dog.sleep()
dog.fly()
# 不能调用私有属性
# dog.__only(self)

只需要在类名后加一个括号里面填上父类的名就行了,当我们需要父类同名的方法但是需要的操作不同,只需重新定义即可。从上面的代码可以类推继承是一层一层的, superdog类继承了dog类dog类又继承了Animal类所以superdog类就继承了Animal类。

多继承

多继承的意思就是,一个类可以继承多个父类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Father_1:
def send1(self):
print("1")
class Father_2:
def send2(self):
print("2")
# 调用多个父类
class son(Father_1,Father_2):
def send(self):
print("son")
# 父类的定义方法不要相同
send=son()
send.send()
send.send1()
send.send2()
# 方法搜索循序
print(Father_1.__mro__)

这种代码很简单一目了然,son继承了Father_1,Father_2。所以他拥有两个父类的特性。

多态

不同对象调用相同的方法(运行时候的绑定状态)

多态和继承有着很亲密的联系,继承可以形成多种状态调用绑定时就会形成多态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class cat(object):
def __init__(self,name):
self.name=name
# 方法和下面的类一样
def cat_play_h(self):
print("catch normel mouth")
class gods_cat(cat):
def cat_play_h(self):
print("catch s uper mouth")
class person(object):
def __init__(self,name):
self.name=name
def order(self,cat):
print("%s order %s chath mouth"%(self.name,cat.name))
# 调用的放方法是同一个但是传入的内容不同
cat.cat_play_h()
# 传入第一给类的方法
cat=cat("cat")
# 传入第二个类的方法
# cat=gods_cat("gods_cat")
xiaoming=person("小明")
xiaoming.order(cat)

明白人一看就可以懂,这里的多态就是cat 和 gods_cat当我们调用同一个方法时它呈现的状态时不一样的。

类属性

类属性时记录类的比如可以定义一个专门记录类被调用几次的属性。

人生苦短,我用python「27」

1
2
3
4
5
6
7
8
9
10
11
12
13
class Test(object):
# 定义类计数器
count=0
def __init__(self,name):
self.name=name
Test.count += 1
print("ss")
# 创建对象
Test1=Test("测试1")
Test2=Test("测试2")
# 输出创建对象的数量,使用类属性进行输出
print(Test.count)
# print(Test2.count)

当我们调用时每一次都被记录到count,可以随时查看这个类被调用了几次,不仅如此我们可以根据自己的情况来定义合适的属性,灵活运用属性使代码更人性化。

类方法

实例方法,类方法,静态方法。有着三种方法。

类方法其实和实例方法类似,不过其第一个参数一般是 cls (约定俗成)而不是 self。但是,如果我们直接将 self 换成 cls 来创建类方法是不对的,因为实例方法的首个参数也是任意的,只是统一使用 self 。python的解释器并没有说看见第一个参数是 cls 就知道这个是类方法,它还是将其当作是实例方法来对待,所以我们需要通过内建函数: classmethod() 来创建类方法。

人生苦短,我用python「28」

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Test(object):
# 定义类计数器
count=0
# 类方法
@classmethod
def show_Test_count(cls):
print("%s"%Test.count)
# 实例方法
def __init__(self,name):
self.name=name
Test.count += 1
Test1=Test("测试")
# 类方法不需要创建对象
Test.show_Test_count()

静态方法

1
2
3
4
5
6
7
class dog(object):
# 定义静态方法不需要传递参数
@staticmethod
def eat():
print("跑")
# 不用定义对象就可以访问
dog.eat()

实例方法只能被实例对象调用,静态方法(由@staticmethod装饰的方法)、类方法(由@classmethod装饰的方法),可以被类或类的实例对象调用。

实例方法,第一个参数必须要默认传实例对象,一般习惯用self。

静态方法,参数没有要求。

类方法,第一个参数必须要默认传类,一般习惯用cls。

方法的综合案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class game:
socer=0
def __init__(self,name):
self.name=name
# 静态方法
@staticmethod
def help_h():
print("帮助")
# 类方法用来记录调用次数
@classmethod
def show_top(cls):
print("分数为%d"%cls.socer)
def begain_h(self):
print("%s开始游戏"%self.name)
# 静态方法不需要创建对象
game.help_h()
# 类方法不需要创建对象
game.show_top()
player=game("god")
player.begain_h()

实战就没什么好讲的了,能够看懂就已经很不错了,毕竟不是自己写的代码,所有东西大体来看都是非常复杂的,但是你分开来看,一点一点分析其实也就那样。

__new__方法和单例

目前我对这两个方法没有什么较深的认识,也不经常用到,提供我练习时的源代码给你们参考。

人生苦短,我用python「29」

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class show(object):
# 元组和字典
def __new__(cls, *args, **kwargs):
print("空间分配")
# 分配空间调用父类方法,这是一个静态方法
instent=super().__new__(cls)
# 返回对象
return instent
def __init__(self):
print("返回")
music=show()
print(music)
class sigle(object):
instance = None
def __new__(cls, *args, **kwargs):
# 判断类的属性是否为空对像
if cls.instance is None:
cls.instance=super().__new__(cls)
# 返回列数性中的对象属性
return cls.instance
# 两个输出的内出地址是相同的
sigle1=sigle()
print(sigle1)
sigle2=sigle()
print(sigle2)

异常处理

从这一章节开始我们就跳出了面向对象这个大坑了,进入另一个大坑。。。。

我们在编程时总会遇到一些异常,比如我们需要得到数字,而用户输入的时字符串,那么整个程序报错系统岂不是崩溃。所以我们需要异常处理来解决类似的问题。

基础语法

人生苦短,我用python「30」

1
2
3
4
5
try:
user=int(input("请输入:"))
except:
print("输入错误sb")
print("欢迎进入")

在有处理的部分加上try: 表示这部分可能有错误

在这里,先执行try后面的代码提示用户输入,如果用户输入错误则进入except执行代码。而最后一行代码不管你输没输错都会执行。

当然还有更加高级的用法,这个下一节在展开描述。

错误类型

我们需要处理的错误有很多类型,比如0不能做分母,有些输入类型错误。针对这些问题我们可以分开处理也可以集中处理。

看一下案例

人生苦短,我用python「31」

1
2
3
4
5
6
7
8
9
try:
user=int(input("请输入:"))
anser=8/user
# except ZeroDivisionError:
# print("不能除以0")
except ValueError:
print("输入错误")
except Exception as result:
print("未知错误")

在这里出现了两个新名词ZeroDivisionError,这是指零不能作为分母如果有这个错误就会执行下面的代码。

Exception as result这个指的是其他的一些错误,我们没有预知的错误。

人生苦短,我用python「31」

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
try:
user=int(input("请输入:"))
anser=8/user
except ZeroDivisionError:
print("不能除以0")
except ValueError:
print("输入错误")
except Exception as result:
print("未知错误")
# # 当输入无任何错误时运行
else:
print("无错误输入")
# 不管有无错误都运行
finally:
print("pass")

再看这个综合案例,从else开始我们可以不用管他们,我们来根据前面学的if语句来理解。try就等于if只是try没有任何参数。下面的except就相当于elif它们都有参数,else两个都一样都是再以上都不满足是出现的。最后有一个finally这个我们可以看作没有,它就相当于执行下面代码。

抛出异常

抛出异常可以当作一个知识点了解一下

人生苦短,我用python「32」

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def pwd_h():
pwd = input("请设置密码:")
if len(pwd)>=8:
return pwd
#创建异常对象
er = Exception("太短")
# 抛出异常
raise er
# 处理异常
try:
# 这句话的作用是打印出p'w'd
print(pwd_h())
except Exception as result:
print(result)

这段代码的注释非常少,因为我在学习的时候就没有太多的描述,这里我讲一下我自己的理解,如果有不正确的地方请大神指正。

pwd_h()是一个函数用来收录用户设置的密码

在这里有一个if语句判断你输入的密码长度是否大于等于8如果满足则返回你输入的密码,这个返回的信息有下面的代码接收print(pwd_h())它的作用是既运行有输出

er=Exception(“太短”)

raise er 注释中说抛出异常,意思就是上面的if没有满足,需要吧异常信息传递出去这个就由print(result)输出了。

到这里异常节就结束了,当然这不是全部基础只是让我们了解一下过程,想要更加精通还需要平时的积累。

操作文件

python对文件可以进行操作,包括读取文件,写入文件等等,这也是一大部分,不过基础学习内容比较少。

我们操作文件分为几步,首先我们需要打开文件,然后需要对文件操作,最后需要关闭文件,python操作和我们平常的步骤一样。

人生苦短,我用python「33」

1
2
3
4
5
6
7
8
# 打开文件
file=open("readtext")
# 读取文件
reg=file.read()
print(reg)
print(len(reg))
# 关闭文件
file.close()

注意这里的文件readtext和python是同一个目录,不要将别的目录的文件也这样打开,这里进行了读取操作,将读取的内容打印出来,print(len(reg))的意思是打印出文本的长度。还有许多可以类似灵活运用,最后一行代码就是关闭文本了。

人生苦短,我用python「33」

1
2
3
4
5
6
7
8
9
10
11
# 打开文件 w覆盖写入 a追加写入
file=open("readtext","a")
# 读取文件
# reg=file.read()
# print(reg)
# print(len(reg))
# 写入文件
file.write(input("请输入写的东西:"))
print("写入成功")
# 关闭文件
file.close()

人生苦短,我用python「33」

这是写入方法,于上一段不同的是打开文件时要注明我想写入的方式,代码注释有用法,如果我们想写入的文本没有创建那么我们进行操作后python会为我们创建这个文本。

逐行读取

很多时候我们需要一行一行地提取信息,所以python就为我们提供了这种方法,可以一次只打印一行,通过前面的内容我们可以想到,循环加上逐行打印是否就可以一行一行地操作了。

看下面的代码:

人生苦短,我用python「34」

1
2
3
4
5
6
7
8
9
file=open("readtext")
while True:
# 逐行进行
get=file.readline()
print(get)
# 没有文件
if not get:
break
file.close()

file中有一个readline属性,它的作用就是只提取一行,在这里我们用Tuer表示一直循环,再向下看,if not get:表示没有得到是真就退出循环。之后的操作就和前面的一样了。

文本拷贝

我们可以利用python来进行拷贝文本的内容,可以将一个文本的内容拷贝到另一个文本。

1
2
3
4
5
6
7
8
9
10
file_y=open("readtext")
# 设置为可写
file_f=open("readtext_f","w")
get=file_y.read()
print(get)
# 将读取内容复制
file_f.write(get)
# 关闭文件
file_y.close()
file_f.close()

在这里要打开两个文本,思路是这样的先让电脑读取一个文本的信息,然后将得到的信息再写入另一个文本,就经过这几步简单的操作就可以实现文本拷贝的操作

大文件拷贝案例

学完之前的代码我们完全可以看懂下面的代码了。

人生苦短,我用python「35」

1
2
3
4
5
6
7
8
9
10
11
12
13
# *-* coding:utf8 *-* 中文
file_y=open("readtext")
# 要写入的文件需要设置可写
file_f=open("readtext_f","w")
while True:
get=file_y.readline()
if not get:
break
file_f.write(get)
file_f.close()
file_y.close()
# u表示告诉编译器使用utf8编码
print(u"世界")

这一给案例就i和我们之前学的分行打印联系上了,当我们遇到很大的文件时,一次性打开就要花费很长的时间,所以我们需要一行一行地打印。

eval

这个作用是输入的内容转换成函数格式,在编程里最忌讳的一种方式,因为但用了这个开发程序,别人就可以从外部来更改你的程序,万一有人知道就是最致命的一段代码了。

人生苦短,我用python「35」

1
2
3
4
5
count=input("请输入算术:")
# eval将输入转换成函数
print(eval(count))
# 调用os函数
# __import__("os").system("ls")

这里有一串代码,自行体会。基础到此结束,谢谢大家观看