IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 2w字Python语法大全 -> 正文阅读

[Python知识库]2w字Python语法大全

文章目录

1. Python

1.1 概述

Python常用于:

  • 人工智能
  • 数据分析
  • 机器学习
  • 爬虫
  • 自动化测试
  • 自动化运维
  • web开发

Python开发的框架:

Google开源机器学习框架:TensorFlow

开源社区主推学习框架:Scikit-learn

百度开源深度学习框架:Paddle

Python是一门解释型语言,因此使用python编程必须先安装python解释器

也因为python是解释型语言,是脚本语言,不是编译型语言,所以代码从上到下运行,是可以不需要主方法的

下面的语法讲解主要讲同java的区别以及python的一些特殊语法

2 基础语法

2.1 语法习惯

  1. 没有分号结尾

  2. 以缩进表示代码块间关系

    所以如果一个if里面或者方法/类里面没东西时一定要写pass,否则报错

  3. 同MATLAB一样,如果一行中仅输入变量名或常量,将打印在控制台

  4. 注释

    单行注释用#

    多行注释用’’'或者""",如下:

#单行注释
'''
多行注释
'''
"""
俺也是多行注释
"""
  1. 使用pycharm进行编程时自带一个控制台终端, 相当于在命令行敲代码

2.2 输入输出函数

2.2.1 输入函数:input()

从python3开始input返回值类型一律为字符串 , 所以在输入数字时要使用int()函数(实际上是类,数据类型)进行转型 , 而java不同, Java转型没有int()函数, int是关键字, python的int是函数而不是关键字

Java转型:

String a = "3";
int b = Integer.parseInt(a);
double c = 3;
int d = (int) c;

python转型:

a = '3'
b = int(a)

在input括号里放的东西会被打印出来, 即input(“提示信息”), 可以将input输入的东西存储为变量:

a = input("请输入你的年龄:")
print(a)
# <class 'str'>
print(type(a))

2.2.2 输出函数:print()

2.2.2.1 参数表

下面是print函数调用参数表

print(*objects, sep=’ ‘, end=’\n’, file=sys.stdout)
  • objects – 复数,表示可以一次输出多个对象。输出多个对象时,需要用 , 分隔
  • sep – 用来间隔多个对象,默认值是一个空格。
  • end – 用来设定以什么结尾。默认值是换行符 \n,我们可以换成其他字符串。
  • file – 要写入的文件对象。
  • print()函数会自动换行
    因为end默认为’\n’,想实现不换行,可以换成其他字符串""(如空)
    示例:
E = [1, 2, 3]
for i in E:
    print(i, end=" ")
# 现在打印结果如下
# 1 2 3

2.2.2.2 分隔符

print打印多个表达式时,用逗号分隔他们,结果是在参数中插入一个空格字符:

print('Age:' , 10)
# Age:  10

但也可以像java一样通过"+"拼接,此时需要前后都是字符串,不会插入空格:

print('Age:'+10)
# Age:10

2.2.2.3 格式化输出:

占位符基本与java一致, 常用占位符:

占位符对象
%s字符串
%d整数
%f浮点数

和Java类似的占位符输出格式:

%06d,表示输出的整数显示位数,不?以0补全,超出当前位数则原样输出

%.2f,表示?数点后显示的?数位数

注意:

? 由于python的格式化输出都是将值转化为字符串输出, 因此不管输出什么都可以只有%s占位符

和Java有区别的地方:

Java格式化输出通过逗号:

int a = 1;
System.out.printf("a=%d", a);

python(不使用%分隔会失去格式化作用):

name = 'zhangsan'
age = 3
print('name=%s' % name) # name=zhangsan
print("abc%s" % "d") # 打印abcd
# 多个变量:
print('name=%s age=%d' % (name,age))

格式化字符串除了%s,还可以写为 f'{表达式}'(从python3.6开始增加的格式化语法,这种语法更加简单易读):

name = 'zhangsan'
age = 3
print(f'我的名字是{name}, 明年{age + 1}岁了')
# 我的名字是zhangsan, 明年4岁了

2.3 变量和数据类型

2.3.1 标识符

  1. 由字母,数字,下划线组成
  2. 不能以数字开头
  3. 区分大小写
  4. 以下划线开头的标识符是特殊意义的
    1. 单下划线开头代表不能直接访问的类属性,需要通过类提供的接口访问,不能用from xxx import *导入
    2. 双下划线开头表示类的私有成员
    3. 双下划线开头和结尾表示python特殊方法专用的标识,如:__xx__表示Python内置标识,__xx__()标识构造方法

2.3.2 数据类型

  1. int : 整数, 包括任意大小
    1. 前缀OB或者Ob,表示二进制
    2. 前缀OO或者Oo,表示八进制
    3. 前缀OX或者Ox,表示十六进制
    4. 关于复数,虚部只能用j表示
  2. float: 浮点数, 小数
  3. str : 字符串, 可以单引号’双引号"三引号’’'或者"""括起来的文字,几种表示无区别
  4. bool : 布尔, 只有True,False俩种值
  5. 空值: 用None表示
  6. list : 列表
  7. tuple : 元组
  8. set : 集合
  9. dict : 字典

可以使用type()函数检测数据类型

2.3.3 变量

变量就是?个存储数据的的时候当前数据所在的内存地址的名字?已, python是弱类型语言, 定义变量不需要指定数据类型:

a = 3
b = 'b'

同时可以使用变量来引用函数
例如: foo = math.sqrt,可以使用foo来计算平方根,如foo(4)

同时python支持链式赋值
可以将多个变量同时关联到同一个值
示例:

x = y = somefunction()
# 上述代码与下面等价
x = somefunction()
y = x
# 但下面代码可能与上面不等价(x和y相等但不相同,指向地址不一样)
x = somefunction()
y = somefunction()

也支持同时给多个变量赋值:

x,y,z = 1,2,3
x,y = y,x
# 还可以用*收集多余的值(带星号的变量最终返回的是一个列表):
a,b,*c = [1,2,3,4]   # c = [3,4]
# 还可以将带星号变量放在其他位置:
a = "w s n b"
first,*mid,last = a.split() # mid = ['s','n']

2.4 转换数据类型的函数

前面将input函数时已经说过使用int()函数可以将数据类型转换为整型了, 类似的, python还有其他可以进行数据类型转换的函数:

函数说明
int(x [,base ])将x转换为?个整数
float(x )将x转换为?个浮点数
complex(real [,imag ])创建?个复数,real为实部,imag为虚部
str(x )将对象 x 转换为字符串
repr(x )将对象 x 转换为表达式字符串
eval(str)?来计算在字符串中的有效Python表达式,并返回?个对象
还可以将字符串中的数据转换成Python表达式原本类型
tuple(s)将序列 s 转换为?个元组
list(s )将序列 s 转换为?个列表
chr(x )将?个整数转换为?个Unicode字符
ord(x )将?个字符转换为它的ASCII整数值
hex(x )将?个整数转换为?个?六进制字符串
oct(x )将?个整数转换为?个?进制字符串
bin(x )将?个整数转换为?个?进制字符串

其中eval()函数较为常用:

2.4.1 eval()

在Python中evel()函数的语法格式为eval(expression, globals=None, locals=None),注意后面还有globals参数和locals参数。eval()函数用于执行一个字符串表达式,并且返回该表达式的值。与eval相近的有exec函数

  • expression:表达式,上面提到evel函数用于执行一个字符串表达式,表达式的内容就放在此处
  • globals:该部分必须是字典!必须是字典!必须是字典!否则程序会出错。当定义了globals 参数之后eval函数的作用域会被限定在globals中, 表示全局命名空间(存放全局变量)
  • locals:该参数掌控局部的命名空间,功能和globals类型,不过当参数冲突时,会执行locals处的参数, 表示当前局部命名空间(存放局部变量), 最优先拿数据的作用域

示例:

a=10;
print(eval("a+1"))
# 11

因为此处没有指定globals和locals,所以直接执行expression部分的内容。该程序的效果等价于a=10 print(a+1)

带globals:

a=10;
g={'a':4}
print(eval("a+1",g))
# 5

由于globals限制了作用域, 因此这里的a就只能是globals中的作用域, 因此打印5

而local是限制最大的作用域, 优先从local中拿数据, 再从globals中拿数据, 最后都没有才会去字典外作用域拿数据, 示例:

a=10
b=20
c=30
g={'a':6,'b':8}
t={'b':100,'c':10}
print(eval('a+b+c',g,t))
# 116

注意:

? eval函数非常的方便,我们可以使用一行代码就实现计算器的功能:

print(eval(input('请输入')))
# 此时我们输入2+3,会直接输出5

? 但是因为它具有可以将字符串转成表达式执行的特性,所以它也就可以去执行系统命令。这样很容易被别有用心的人用来执行系统命令,删除关键系统文件, 因此eval函数必须慎用

除此之外eval函数还可以将字符串中的数据转换成Python表达式原本类型:

str1 = '10'
str2 = '[1, 2, 3]'
str3 = '(1000, 2000, 3000)'
# 输出<class 'int'>
print(type(eval(str1)))
# <class 'list'>
print(type(eval(str2)))
# <class 'tuple'>
print(type(eval(str3)))

2.4.2 exec函数

前面介绍了eval函数可以实现自动运行字符串中的计算表达式, exec函数类似, 但是exec函数能够动态地执行复杂的Python代码, 也就是说exec函数除了执行计算表达式字符串之外, Python代码字符串也是可以直接通过exec函数执行的

看下区别:

# 报错, 无法执行a=3这种Python代码
eval('a=3 ; print(a)')
# 输出3
exec('a=3 ; print(a)')

因此我们可以读取 Python代码的txt文件, 再通过exec函数运行

类似于eval函数, 同样有globals和locals参数

2.5 import语法

俩种模块导入:

  1. import 模块名

    只导入模块,不导入模块中具体对象,使用时要用模块名.对象名的方式进行访问

  2. from 模块名 import 对象名1(函数名) 对象名2(函数名) …

    只能导入模块中具体对象,使用时直接使用对象名不需要加上模块名(但是这种方法可能导致导入的对象或者函数与自己写的代码重名)

    例如当导入了俩个具有相同名字函数的模块时, 执行的时候调?到的是后?导?的模块的功能

    一次导入模块中所有对象:from 模块名 import *

    相当于导入一个模块中的一个函数并为他创建一个对象, 是这个意思吗?

  3. 俩种都可以在后面加上: as 别名

和Java区别:

? Java的import更多的是导入类或者静态变量

2.6 运算符

  1. ** : 幂运算

  2. / : 相除,结果为浮点数

  3. // : 整除

  4. % : 取余,当除数(后面那个)是负数时结果为负,其他为正

  5. 逻辑与: and
    逻辑或: or
    逻辑非: not

    小知识:python中的布尔运算符在判断时只做必要的计算
    如:x and y中,如果x为假直接返回x,x为真则返回y,而不关心y的具体(在python中除了少数值外其他几乎所有值都为真)
    而在x or y中同样如此,x为真直接返回x,为假则返回y
    以下代码就利用了这种行为:

    name = input('Please enter your name:') or 'unknown'
    '''
    如果没有输入名字,则可以直接将name设置为'unknown'
    但在大多数情况下,你宁愿使用条件表达式,而不耍这样的短路花样
    '''
    
  6. 按位与: &,如5&6,转换为二进制101 & 110 = 100 = 4,所以5&6=4
    按位或: 5 | 6 = 101 | 110 = 111 = 7,所以5|6 = 7
    按位异或: 5 ^ 6 = 101 ^ 110 = 011 = 3,所以5 ^ 6 = 3
    tips:

    异或是当符号前后俩者分别为T和F时才为T(所以运算针对二进制),俩个数字做异或时,先转换成二进制数,再把每一位的数字俩俩对比

  7. >> << : 右移,左移

  8. == != : 是否等于,是否不等

  9. is,is not : 身份运算符
    in,not in : 成员运算符

  10. 运算符优先级:

运算符描述(由上至下由高到低)
**
~ + -取反,正号,负号

与Java主要区别:

  • **:幂, /相除, //整除

  • 没有+±-, 但是有+=和-=等

  • Java 判断变量age是不是大于18小于20:

    age > 18 && age < 20

    python:

    age > 18 and age < 20

    或者:和链式赋值一样,python也支持链式比较(java不支持)

    18 < age < 20

2.6.1 is,is not与==,!=

is,is not对比的是俩个变量的内存地址,==,!=对比的是俩个变量的值.由此:

  1. 对于地址不可变的类型(str等),is,==是完全等价的(==时代表俩者相等,is需要俩者相同,即地址一致)
  2. 对于地址可变的类型(list(列表),dict(字典),tuple(元组),set(集合)等),俩者有区别,但python对字符串可以直接使用==,因为str是不可变的类型,这是与java不同的
a = "Hello"
b = "Hello"
print(a is b,a == b)#输出为True True
a = ["Hello"]#可变的列表类型
b = ["Hello"]
print(a is b,a == b)#输出为False True

和Java区别:

? Java是对于基本数据类型, ==判断值是否相等, 对于引用数据类型, ==判断地址, equals判断值(因为一般引用数据类型的equals是被重写过的)

2.6.2 三目运算符

语法:

条件成?执?的表达式 if 条件 else 条件不成?执?的表达式

示例:

a = 1
b = 2 
c = a if a > b else b
print(c)
# 2

Java语法:

int c = 2>1 ? 2:1;
// c = 2

2.6.3 交换变量值

使用Java或者C的写法交换:

# 1. 定义中间变量
c = 0

# 2. 将a的数据存储到c
c = a

# 3. 将b的数据20赋值到a,此时a = 20
a = b

# 4. 将之前c的数据10赋值到b,此时b = 10
b = c

print(a) # 20
print(b) # 10

用python自带的特点交换:

a, b = 1, 2 
a, b = b, a
print(a) # 2
print(b) # 1

2.7 流程控制基本语句

2.7.1 if-elif-else

条件语句:if,elif,else.不需要括号,但需要在结尾加上冒号:

if 条件:
	条件成?执?的代码1
	条件成?执?的代码2
elif 条件2:
    条件2成?执?的代码1
	条件2成?执?的代码2
else:
    都不成?执?的代码1
	都不成?执?的代码2

示例:

if True:
	print('条件成?执?的代码1')
    print('条件成?执?的代码2')
# 下?的代码没有缩进到if语句块,所以和if条件?关
print('我是?论条件是否成?都要执?的代码')

和Java区别:

? else if变成了elif, 多了个:少了个()

注意:

  • 布尔表达式(如用作if语句中的条件)时,以下值都将被解释为假:

False None 0 “” () [] {}

  • in可以用于条件表达式中
  • 使用两个字符串中的字符执行Python字符串比较
    两个字符串中的字符被一一比较
    当找到不同的字符时,将比较它们的Unicode值。Unicode值较低的字符被认为较小
    可以使用ord()函数来获取Unicode码
    比较序列时同样将元素一一比较

2.7.2 while

while循环: 无括号,加冒号 :

while 条件:
 条件成?重复执?的代码1
 条件成?重复执?的代码2
 ......

示例:

i = 1
result = 0
while i <= 100:
   result += i
   i += 1
# 输出5050
print(result)

python的循环也支持break,continue ,不管是for循环还是while循环, 效果都和Java一致

while-else:

? 可以在循环中加入else子句, 此时的else子句仅在break没有执行时执行 (即循环正常结束时)

示例:

i = 1
result = 0
while i <= 100:
   result += i
   i += 1
else:
    result += 1
# 输出5051
print(result)

i = 1
result = 0
while i <= 100:
   result += i
   i += 1
   if i == 3:
   		break
else:
    result += 1
# 0+1+2,接着被break, 没有经过else,直接输出3
print(result)

2.7.3 for循环

for…in循环:遍历任何序列(或任何可迭代对象) , 序列下面会讲:

常用到的可迭代的对象包括:string, list, dict, tuple, generator, range函数

for 临时变量 in 序列:
 重复执?的代码1
 重复执?的代码2
 .....

示例:

str = "Python"
for s in str:
    print(s) # 打印Python,每一个字母换一行
for i in range(0,5):
    print(i) # 打印0到4
# 遍历字典
d = {'x':1,'y':2}
for key in d:
    print(key,d[key]) 
# 或者使用items函数直接得到键值对(items()函数以元组形式返回键值对)
for key value in d.items():
    print(key,value) 

for-else:

? 可以在循环中加入else子句(循环下面,缩进与for,while一个位置),此时的else子句仅在break没有执行时执行 (即循环正常结束时)

3. 常用模块与函数

3.0 Python的模块概述

python中的模块含义:

模块是包含了所定义的函数和变量的文件,必须以.py为拓展名

也就是说一个.py文件就是一个模块, 一个模块中可以包含若干函数和变量以及类等

在实际开中,当?个开发?员编写完?个模块后,为了让模块能够在项?中达到想要的效果,这个开发?员会??在py?件中添加?些测试信息(定义函数并调用函数), 简单示例:

def testA(a, b):
	print(a + b)
    
testA(1, 1)

因为Python的解释型语言, 并且已经调用了这个函数, 所以不管是这个模块运行的时候, 还是其他导入了这个模块的文件运行的时候, 都会运行这段测试代码

但是一般我们不希望导入这个模块时也去运行测试代码, 因此测试代码经常是这样子写的:

def testA(a, b):
	print(a + b)
    
    
# 只在当前?件中调?该函数,其他导?的?件内不符合该条件,则不执?testA函数调?
if __name__ == '__main__':
	testA(1, 1)

其中if __name__ == '__main__':相当于这个模块的主函数

当导??个模块,Python解析器对模块位置的搜索顺序是:

  1. 当前?录

  2. 如果不在当前?录,Python则搜索在shell变量PYTHONPATH下的每个?录。

  3. 如果都找不到,Python会察看默认路径。UNIX下,默认路径?般为/usr/local/lib/python/

    模块搜索路径存储在system模块的sys.path变量中。变量?包含当前?录,PYTHONPATH和由安装过程决定的默认?录。

注意:

  • ??的?件名不要和已有模块名重复,否则导致模块功能?法使?

  • 使?from 模块名 import 功能 的时候,如果功能名字重复,调?到的是最后定义或导?的功能

3.0.1 _all_列表

如果?个模块?件中有 __all__ 变量(列表),当使? from xxx import * 导?时,只能导?这个列表中的元素

同样的, 包下的_init_.py下定义的_all_变量可以控制使? from xxx import *导入这个包时能导入的模块

3.1 断言函数

断言函数作用:
断言函数是对表达式布尔值的判断,要求表达式计算值必须为真。可用于自动调试
如果表达式为假,触发异常;如果表达式为真,不执行任何操作
举例:

# 以下都为真,正常执行
assert(1 == 1)
assert(5 > 1)
a = "hello"
b = "hello"
assert(a == b)
# 以下为假,程序报错:
assert(1 > 100)

3.2 数学函数

先引入数学模块math,引入后即可使用.以求平方根函数sqrt(x)为例:

import math
math.sqrt(1024)

常用数学函数:

函数描述
abs(x)返回绝对值
ceil(x)往上取整,如ceil(1.1)返回2
floor(x)往下取整
exp(x)返回e的x次幂
log(x)返回以e为底,x的对数
pow(x,y)返回x的y次幂
sqrt(x)返回x的平方根
factorial(x)返回x的阶乘

3.3 随机函数

先引入random模块
下面简单介绍几个常用函数:

import random
# 1. random(x)函数,随机生成0到1范围内的实数
random.random()
# 2. random(x)函数,随机生成x到y范围内的整数
random.randint(1,10)
# 3. uniform(x,y)函数,随机生成x到y范围内的实数
random.uniform(1,10)

3.4 range()函数和xrange()函数

  1. range(start,stop,step)
    返回一个数字列表,包含起始值,不包含结束值 (左闭右开)
    起始值可以忽略,默认为0
    步长可以忽略,默认为1
  2. xrange()是一个类,返回一个xrange()对象,遍历后只返回一个值

3.5 turtle模块(海龟绘图法)

存在一只虚拟的海龟,让他在"画布"上通过前进后退左转右转旋转抬起放下等操作画图

4. 自带数据结构(序列)

4.1 序列概述

序列是一种数据存储方式,用来存储一系列的数据。在内存中,序列就是一块用来存放多个值的连续的内存空间

序列中存储的是整数对象的地址,而不是整数对象的值

python中常用的序列结构有:字符串、列表、元组、字典、集合

元组可以理解成不可变的列表,多数情况下使用列表

4.2 通用的序列操作

4.2.1 索引

序列中所有元素编号从0开始

可以使用负数索引,-1表示最后一个元素

对于序列字面量,可以直接执行索引操作,不用先赋值给变量

如:‘Hello’[0] 结果为’H’

list1 = [1,2,3];list[-1]为3


4.2.2 切片

索引访问单个元素,切片访问特定范围内的元素(左闭右开区间)

为此,可用俩个索引并用:隔开

如果切片开始于序列开头,可省去第一个索引

如果切片结束于序列末尾,可省去第二个索引

要指向整个序列,可将俩个索引都省略

可以同时使用正数负数索引,但前一个索引不能位于后一个索引之后,否则结果为空序列

示例:

numbers = [1,2,3,4,5,6,7,8,9,10]
numbers[0:3]   # [1,2,3]
numbers[:2]    # [1,2]
numbers[8:]    # [9,10]
numbers[7:-1]  # [8,9]

设置步长:
通常在省略步长的切片中步长默认为1,但也可以在第二个索引后加上步长, 正负整数均可:

序列[开始位置下标:结束位置下标:步?]


4.2.3 运算符

运算符规则:

在这里插入图片描述

集合(set)和字典(dict)都不能+和*

但是集合(set)能in和not in

4.2.3.1 相加(拼接):+

4.2.3.1 序列相加(拼接):+

可以使用+来拼接序列,但只能拼接相同类型的序列


4.2.3.2 乘法:*

可以将序列与数x相乘,将重复这个序列x次来创建新序列

示例:

[0] * 4
# [0,0,0,0]

可以使用None初始化列表(初始化长度,为空列表)

[None] * 10

4.2.3.3 成员资格:in,not in

要检查特定的值是否包含在序列中可以使用布尔运算符in
in检查是否满足指定的条件,满足返回True,不满足返回False(Python中TrueFalseNone等首字母大写,与java不同)
示例:

x = 'python'
'p' in x # True

4.2.4 公共函数

4.2.4.1 获得序列的长度,最大值和最小值

len()函数返回序列包含的元素个数

max()函数返回序列中最大的元素

min()函数返回序列中最小的元素

4.2.4.2 删除

del 或 del()函数:

list1 = [1,2,3]

del list1
del(list1)

del list1[0]

4.2.4.3 enumerate()函数

enumerate(可遍历对象, start)函数?于将?个可遍历的数据对象(如列表、元组或字符串)组合为?个索引序列(生成一个元组),同时列出数据和数据下标,?般?在 for 循环当中, start参数?来设置遍历数据的下标的起始值,默认为0

示例:

list1 = [1, 2]

for i in enumerate(list1):
    print(type(i))
    print(i)
for index, char in enumerate(list1, start=1):
    print(type(index))
    print(type(char))
    print(f'下标是{index}, 对应的字符是{char}')

结果:

在这里插入图片描述

4.3 str(字符串)

严格意义上来讲, 字符串并不是python的序列, 但是很多序列的语法用在字符串上也都是适用的, 因此放在这里

python常用API:

4.3.1 查找

所谓字符串查找?法即是查找?串在字符串中的位置或出现的次数:

4.3.1.1 find

fifind():检测某个?串是否包含在这个字符串中,如果在返回这个?串开始的位置下标,否则则返回-1:

字符串序列.find(?串, 开始位置下标, 结束位置下标)

注意:开始和结束位置下标可以省略,表示在整个字符串序列中查找

mystr = "hello world and Python and Java"
print(mystr.find('and')) # 12
print(mystr.find('and', 15, 30)) # 23
print(mystr.find('ands')) # -1

4.3.1.2 index()

index():检测某个?串是否包含在这个字符串中,如果在返回这个?串开始的位置下标,否则则报异常:

字符串序列.index(?串, 开始位置下标, 结束位置下标)

注意:开始和结束位置下标可以省略,表示在整个字符串序列中查找

mystr = "hello world and Python and Java"
print(mystr.index('and')) # 12
print(mystr.index('and', 15, 30)) # 23
print(mystr.index('ands')) # 报错

4.3.1.3 rfind()和rindex()

rfind(): 和find()功能相同,但查找?向为右侧开始

rindex():和index()功能相同,但查找?向为右侧开始

mystr = "hello world and Python and Java"
print(mystr.rfind('and')) # 23
print(mystr.rfind('and', 15, 30)) # 23
print(mystr.rfind('ands')) # -1

mystr = "hello world and Python and Java"
print(mystr.rindex('and')) # 23
print(mystr.rindex('and', 15, 30)) # 23
# print(mystr.rindex('ands')) # 报错

4.3.1.4 count()

count():返回某个?串在字符串中出现的次数:

字符串序列.count(?串, 开始位置下标, 结束位置下标)

注意:开始和结束位置下标可以省略,表示在整个字符串序列中查找

mystr = "hello world and Python and Java"
print(mystr.count('and')) # 2
print(mystr.count('and', 15, 30)) # 1
print(mystr.count('ands')) # 0

4.3.2 修改

所谓修改字符串,指的就是通过函数的形式修改字符串中的数据

4.3.2.1 replace():替换

字符串序列.replace(旧?串, 新?串, 替换次数)

注意:替换次数如果查出?串出现次数,则替换次数全部出现次数

返回修改后的字符串

同时数据按照是否能直接修改分为可变类型和不可变类型两种。字符串类型属于不能直接修改数据的类型, 即不可变类型, 因此使用replace修改后原字符串不变

mystr = "hello world and Python and Java"
# hello world he Python he Java
print(mystr.replace('and', 'he')) 
# hello world he Python and Java
print(mystr.replace('and', 'he', 1)) 
# 不可变数据类型,不变:
# hello world and Python and Java
print(mystr) 

4.3.2.2 join():合并字符串

join():??个字符或?串合并字符串,即是将多个字符串合并为?个新的字符串:

字符或?串.join(多字符串组成的序列)
list1 = ['hello', 'world', 'and', 'python']
t1 = ('aa', 'b', 'cc', 'ddd')
# 结果:hello_world_and_python
print('_'.join(list1))
str = '...'
# 结果:aa...b...cc...ddd
print(str.join(t1))

和直接序列相加不一样

4.3.2.3 大小写转换

title():将字符串每个单词?字?转换成?写

都是返回修改后的字符串,原字符串不变

str = 'hello world'
# Hello World
print(str.title())
# hello world
print(str)

lower():将字符串中全部?写转?写

str = 'Hello woRld'
# hello world
print(str.lower())

upper():将字符串中全部?写转?写

str = 'Hello woRld'
# HELLO WORLD
print(str.upper())

4.3.2.4

4.3.3 分隔:split()

split():按照指定字符分割字符串:

字符串序列.split(分割字符, num)

注意:返回分割后的列表

num表示的是分割字符出现的次数,即将来返回数据个数为num+1个

如果没指定num则将字符串按照全部分割字符切分

mystr = "hello world and Python and Java"
# 结果:['hello world ', ' Python ', ' Java']
print(mystr.split('and'))
# 结果:['hello world ', ' Python and Java']
print(mystr.split('and',  1))
# 结果: ['hello', 'world', 'and Python and Java']
print(mystr.split(' ',  2))
# 不可变数据类型,不变:
# hello world and Python and Java
print(mystr)

4.4 list(列表ArrayList)

4.4.1 概述

列表:用于存储任意数目、任意类型的数据集合。

列表是内置可变序列,是包含多个元素的有序连续的内存空间

列表定义的标准语法格式:

a = [10,20,30,40]

其中,10,20,30,40 这些称为:列表 a 的元素。

列表中的元素可以各不相同,可以是任意类型。比如:

a = [10,20,'abc',True]

python的序列全都支持元素以各不相同,任意类型

Python 的列表大小可变,根据需要随时增加或缩小

添加元素可以直接使用索引也可以使用append()方法或者extend方法,insert()方法

list可以修改指定下标数据:

name_list = ['Tom', 'Lily', 'Rose']
name_list[0] = 'aaa'
# 结果:['aaa', 'Lily', 'Rose']
print(name_list)	

4.4.2 API

方法要点描述
list.append(x)增加元素在list的尾部插入x
list.extend(aList)增加元素将列表aList的所有元素加到list的尾部
list.insert(index,x)增加元素在指定位置index加入元素x
list.remove(x)删除元素在列表list中删除首次出现的指定元素x
del list[index]删除元素删除列表指定位置的元素
list.pop()删除元素移除元素,默认从最后移除,返回该元素值;括号中可加入元素索引值来移除
list.clear()删除所有元素删除列表所有元素,并不是删除列表对象
list.index(x)访问元素返回第一个元素x的索引位置,不存在x元素时抛出异常
list.count(x)计数返回元素x在list中出现的次数
len(list)列表长度返回列表中包含的元素个数
list.sort()排序所有元素原地排序
list.sorted()排序建立一个副本再排序,返回副本列表,原列表不变
list.reverse()颠倒顺序按相反顺序排列列表中的元素,不返回任何值,如[1,2]变成[2,1]
list.copy()复制列表常规复制方法只是将另一个名称关联到列表,copy()方法关联到列表的副本

方法sort和sorted接受两个参数:key和reverse,这俩个参数通常按名称指定
多数情况下,将key设置为一个自定义函数
参数reverse设置为True时将反序排列列表,如[8,4,1]这样子的降序排序

4.4.3 其他创建方式

list()创建列表, range()创建列表
使用 list()可以将任何可迭代的数据转化成列表。
range()可以帮助我们非常方便的创建整数列表,语法格式为:

range([start,] end [,step])    

示例:

a = list(range(10))  # 0到9
b = list(range(0.20,2))  # 0到20,步长为2

4.4.4 遍历

while:

name_list = ['Tom', 'Lily', 'Rose']
i = 0
while i < len(name_list):
    print(name_list[i])
    i += 1

for:

name_list = ['Tom', 'Lily', 'Rose']
for i in name_list:
    print(i)

4.4.5 列表嵌套

相当于二维数组

name_list = [['?明', '?红', '?绿'], ['Tom', 'Lily', 'Rose'], ['张三', '李四', '王五']]
# 李四
print(name_list[2][1])

4.5 tuple(元组不可变list)

相当于 不可变的list列表

通过()创建元组。小括号可以省略

a = (10,20,30)或者a = 10,20,30

**注意:**如果元组只有一个元素, 则必须后面加逗号

这是因为解释器会把(1)解释为整数 1, (1,)解释为元组。

元组中的元素值是不允许修改的,但我们可以对元组进行连接组合:
示例:

a = (1,2,3,5)
b = (6,7)
c = a + b
# (1, 2, 3, 5, 6, 7)
print(c)
a = a[:3] + (4,) + a[3:]
# (1, 2, 3, 4, 5)
print(a)

元组可以用作映射(字典)中的键,以及集合(set)中的成员,而列表不行, 因为列表等是可变数据类型

元组数据不?持修改,只?持查找,具体如下:

  • 按下标或者切片

  • index():查找某个数据,如果数据存在返回对应的下标,否则报错,语法和列表、字符串的index

    ?法相同

  • len():统计元组中数据的个数

4.6 dict(字典)(映射map)

4.6.1 概述

相当于java的map

映射: 通过名称来访问各个值的数据结构

字典是python中唯一的内置映射类型,其各个值不按顺序排列,而是存储在键下,即键值对

键可以是数,字符串或元组等不可变的类型, 不能是列表(list),集合(set),字典(dict)等可变类型
字典中值可以重复,但键必须是唯一的(映射)

4.6.2 创建字典

  1. 直接创建
    字典放在花括号{}中,键和值之间用冒号(:)分隔,每个键值对之间用逗号(,)分隔

    示例:

a = {'x': 1,'y' : 2}
# 创建空字典
a = {}
  1. 使用dict函数(实际上dict不是函数,而是一个类)

    可使用函数dict从其他映射或键值对序列来创建字典
    示例:

items = [('name','Gumby'),('age',10)]
# {'age':10,'name':'Gumby'}
d = dict(items)  

? 还可以使用关键字参数来调用这个函数,如下:

# {'age':10,'name':'Gumby'}
d = dict(name = 'Gumby',age = 10)
# 创建空字典:
c = dict()

4.6.3 字典的基本操作

字典序列[key] = 值有则覆盖, 无则新增

API:

函数描述
len(dict)返回键值对个数
del dict[k]删除键为k的项
k in dict检查字典中是否包含键为k的项
dict.clear()删除字典中的所有项,不返回值
dict.copy()返回一个键值对与原来字典相同的新字典,但这个方法是浅复制,即值是原件不是副本,修改新字典的值,原件受影响
dict.deepcopy()深复制,但deepcopy是模块copy中的函数,需要导入
dict.get(k)通过键访问值,这种方法相较于直接访问更宽松(因为可以访问不存在的键,返回None)
dict.items()以元组的方式返回键值对
dict.gets()
dict.values()

dict.gets():

dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
# dict_keys(['name', 'age', 'gender'])
print(dict1.keys()) 

dict.values():

dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
# dict_values(['Tom', 20, '男'])
print(dict1.values()) 

dict.gets():

dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
# dict_items([('name', 'Tom'), ('age', 20), ('gender',
'男')])
print(dict1.items()) 

4.6.4 遍历

dict1 = {'name': 'Tom', 'age': 20, 'gender': '男'}
for key in dict1.keys():
    print(key)


for value in dict1.values():
    print(value)

for item in dict1.items():
    print(item)
    
    
for key, value in dict1.items():
    print(f'{key} = {value}')
    
    

4.7 set(集合HashSet)

4.7.1 概述

创建集合使? {} 或 set() , 但是如果要创建空集合只能使? set() ,因为 {} ?来创建空字典

集合中的每一个元素不能出现多次,并且是无序存储的,相当于Java的HashSet

因此集合没有+,*等操作

同时也不能索引,切片

s1 = {10, 30, 20, 10, 30, 40, 30, 50}
# 随机无序, 自动去重
print(s1)

s2 = set('abcdefg')
# {'f', 'a', 'd', 'g', 'c', 'e', 'b'}
print(s2)

s3 = set()
# 打印:set()
print(s3)
# 打印:<class 'set'>
print(type(s3))

s4 = {}
# 打印:{}
print(s4)
# 打印:<class 'dict'>
print(type(s4)) # dict

注意:

集合可以快速完成列表去重

但集合不?持下标

4.7.2 增加数据

  • add(),参数是基本数据类型

    当向集合内追加的数据是当前集合已有数据的话,则不进?任何操作

    返回None

  • update(), 追加数据, 参数序列

    返回None

  • remove(),删除集合中的指定数据,如果数据不存在则报错

  • discard(),删除集合中的指定数据,如果数据不存在也不会报错

  • pop(),随机删除集合中的某个数据,并返回这个数据

4.7.3 in和not in

集合set是可以进行in和not in,前面表格有误

4.8 推导式

只有列表,集合和字典有推导式

4.8.1 列表推导式

列表推导式:??个表达式创建?个有规律的列表或控制?个有规律列表。

列表推导式?叫列表?成式

如果不使用推导式创建有规律的列表, 例如创建?个0-10的列表:

# 1. 准备?个空列表
list1 = []

# 2. 书写循环,依次追加数字到空列表list1中 i = 0
while i < 10:
    list1.append(i)
    i += 1
    
    
print(list1)

# 或者:
for i in range(10):
    list1.append(i)

但如果使用了推导式:

list1 = [i for i in range(10)]

解释:

  • 代码写在[]中, 代表生成的是一个列表

  • 语法:

    变量 for 变量 in 函数(通常都是range) [if 变量满足的条件]

    []代表可选

示例:

  1. 可以通过range参数获得指定规律的列表, 例如0-10的偶数列表:
list1 = [i for i in range(0, 10, 2)]
  1. 通过if语句获得指定规律的列表, 还是0-10的偶数列表:
list1 = [i for i in range(10) if i % 2 == 0]
  1. 希望列表中存放序列, 使用多个for, 例如存放元组:
list1 = [(i, j) for i in range(1, 3) for j in range(3)]
# [(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]

4.8.2 字典推导式

字典推导式作?:快速合并列表为字典创建?个有规律的字典提取字典中?标数据

  1. 将两个列表合并为?个字典:
list1 = ['name', 'age', 'gender']
list2 = ['Tom', 20, 'man']

dict1 = {list1[i]: list2[i] for i in range(len(list1))}
  1. 创建?个有规律的字典
dict1 = {i: i**2 for i in range(1, 5)}
# {1: 1, 2: 4, 3: 9, 4: 16}
print(dict1) 
  1. 提取字典中?标数据
counts = {'MBP': 268, 'HP': 125, 'DELL': 201, 'Lenovo': 199, 'acer': 99}

# 需求:提取上述电脑数量?于等于200的字典数据
count1 = {key: value for key, value in counts.items() if value >= 200}
# {'MBP': 268, 'DELL': 201}
print(count1) 

4.8.3 集合推导式

集合推导式作?:创建?个有规律的集合

list1 = [1, 1, 2]
set1 = {i ** 2 for i in list1}
# {1, 4}
print(set1) 

4.9 迭代器

迭代是python中访问集合元素的一种非常强大的一种方式。迭代器是一个可以记住遍历位置的对象,因此不会像列表那样一次性全部生成,而是可以等到用的时候才生成,因此节省了大量的内存资源。迭代器对象从集合中的第一个元素开始访问,直到所有的元素被访问完。迭代器有两个方法:__iter__()__next()__方法

类似于list、tuple、str 等类型的数据可以使用for …… in…… 的循环遍历语法从其中依次拿到数据并进行使用,我们把这个过程称为遍历,也称迭代。python中可迭代的对象有**list(列表)、tuple(元组)、dirt(字典)、str(字符串)、set(集合)**等

创建一个可迭代的对象:只要此对象含有**iter方法,那么它就是一个可迭代的对象**, isinstance()函数以及Iterable来判断一个对象是否是可迭代的对象, 是一个**Iterable(可迭代对象)**则结果返回为True;否则,结果为False

print("判断是否是可迭代的对象:", isinstance(class1,Iterable))

创建迭代器:一个类(对象)只要含有iter”、"next"两个方法,就将其称为迭代器。__iter__方法返回一个特殊的迭代器对象,而这个迭代器对象自动实现了_next__方法,并返回一个值,最后通过抛出异常StopIteration来结束迭代,

同样可以通过isinstance()函数以及Iterator判断是否是迭代器

print("判断是否是迭代器:", isinstance(class1,Iterator))

迭代器代码示例:

class Classmate(object):
    """定义一个同学类"""
 
    def __init__(self):
        self.name = list()
        self.name_num = 0
 
    def add(self,name):
        self.name.append(name)
    
    def __iter__(self):
        return self   # 返回本身
 
    def __next__(self):
       if self.name_num < len(self.name):
           ret = self.name[self.name_num]
           self.name_num += 1
           return ret
 
        # 抛出异常,当循环后自动结束
       else:
           raise StopIteration

迭代器最核心的功能就是可以通过**__next__方法的调用来返回下一个值**。而这个值不是从已有的数据中读取的,而是通过程序按照一定的规则生成的。这也就意味着我们可以不再依赖一个现存的数据集合来存放数据,而是边用边生成,这样的好处就是可以节省大量的内存空间

以实现斐波那契数列(0,1,1,2,3,5,8,13,21……后一项总是等于前两项的和)为例:

方法一:

a = 0
b = 1
myFibonacci = list()
 
nums = int(input("请输入需要生成Fibonacci数列项的个数:"))
 
i = 0
while i < nums:
    myFabonacci.append(a)
    a,b = b,a+b
    i += 1
 
for num in nums:
    print(num)

方法二:

class Fibonacci(object):
    """斐波那契数列得迭代器"""
    def __init__(self,nums):
        self.nums = nums   # 传入参数,生成斐波那契数列的个数
        self.a = 0   
        self.b = 1
        self.i =0    # 用于记忆生成的个数
    def __iter__(self):
        return self
    def __next__(self):

       ret = self.a   # 记忆第一个数

       if self.i < self.nums:
            self.a, self.b = self.b,self.a +self.b
            self.i += 1
            return ret
       else:
           raise StopIteration   # 停止迭代
           
           
nums = int(input("请输入需要生成Fibonacci数列项的个数:"))
fobo = Fibonacci(nums)

for num in fobo:
    print(num)

虽然结果相同,但实际效果却相差巨大。来看一下方法一,他是通过while循环立即生成一个列表用来存放数据,接着再从已有的数据中读取所需数据,而这需要占用一定的内存空间;再来看一下方法二,它并没有用到列表,而是返回一个迭代器,在需要的时候生成相关数据。纵观以上两种方法,在生成个数较小时,两者相差不大,但当生成个数是10万,100万,1000万呢?前者需要消耗大量的内存资源,而后者仅需占用一点内存即可。这也是python2中range()函数和python3中range()函数的不同点,python3的range()函数采用了迭代器的方式,不再依赖于现有的数据集合,也就相当于python2中的xrange()函数

总结:

可迭代对象不一定是迭代器。

迭代器一定是可迭代对象。

容器类型(list tuple dict str set )是可迭代对象但不是迭代器。

4.10 拆包

对字典进?拆包,取出来的是字典的key,方便我们操作value

# 元组:
def return_num():
    return 100, 200

num1, num2 = return_num()
print(num1) # 100
print(num2) # 200


# 字典
dict1 = {'name': 'TOM', 'age': 18} a, b = dict1

# 对字典进?拆包,取出来的是字典的key
print(a) # name
print(b) # age
print(dict1[a]) # TOM
print(dict1[b]) # 18

5. 基础++语法

5.1 函数

5.1.1 概述

函数通过关键字def定义,def后跟函数名与圆括号,括号内放形参,以冒号结尾.

def sum(a, b):
    return a+b
  1. 变量作用域:全局变量与局部变量:

    一般在函数体外声明的都是全局变量,在函数内部声明的都是局部变量

    所以为了在函数中使用全局变量(修改),就得使用global语句, 不然操作的是局部变量

    global语句相对于在函数内部或循环内部声明变量是全局变量,使得函数内可以使用和改变全局变量

a = 1

def sum():
    global a
    a = 2
    
sum()
# 2
print(a)
  1. 可以在函数体最前面使用多行注释写函数的说明文档

    使用help(函数名)即可查看说明文档

  2. return语句

    跳出函数并返回一个值

    没有返回值的return语句相当于return None

    return a, b 写法,返回多个数据的时候,默认是元组类型

    return后?可以连接列表、元组或字典,以返回多个值

  3. 直接打印方法名不加括号,打印结果:

    <function sum at 0x000002291D63B948>

  4. 默认参数
    通过声明形参时为一些参数赋值使一些参数是"可选的,有默认值的"

def say(msg, times = 1):
    print(msg * times)

say("Peter")
say("Peter", 3)
  1. 关键参数

    调用方法时为参数赋值默认是按照定义顺序赋值的

    但当参数很多时,且只想指定其中的部分,可以在调用函数时为这些参数赋值(通过参数名= 值)

    优点:不用担心参数顺序.且假设其他参数都有默认值时可以只给我们想要的那些参数赋值

def func(a, b=2, c=3)
    print(a,b,c)
func(1) # 1 2 3
func(1, 5) # 1 5 3
func(1, c=10) # 1 2 10
func(c=20, a=30) # 30 2 20
  1. 收集参数

  2. 在形参前加上*,会收集所有剩下的参数(未被指定的非关键参数)到一个元组中

    如果没有可供收集的参数,该参数将是一个空元组

    带星号参数后面也可以继续放参数,此时调用函数时对后面参数要使用名称来指定(关键参数)

    星号不会收集关键字参数

    收集关键参数可以使用**,此时该参数收集为一个字典

    示例:

def demo_1(text, *s):
    print(text)
    print(s)
    
demo_1(sss,s1,s2)
/* 结果:
sss
(s1,s2)
*/

def demo_2(text, *s,text2):
    print(text)
    print(s)
    print(text)
    
demo_2(sss,s1,s2,text2 = t)
/*结果:
sss
(s1,s2)
t
*/

def demo_3(**s):
    print(s)
    
demo_3(x = 1, y = 2, z = 3)
# 结果:{'z':3,'y':2,'x':1}

5.1.2 引用

字符串,数和元组(tuple)等不可变的数据类型为参数时形参不变

列表(list)等可变的数据类型为参数时,实参改变

这是因为在python中,值是靠引?来传递来的

可以通过id()来得到变量在内存中的地址

这就相当于Java的实参为基本数据类型时实参不变, 为引用数据类型时实参改变

# 1. int类型
a = 1
b = a

print(b) # 1
print(id(a)) # 140708464157520
print(id(b)) # 140708464157520

a = 2
print(b) # 1,说明int类型为不可变类型
print(id(a)) # 140708464157552,此时得到是的数据2的内存地址
print(id(b)) # 140708464157520

# 2. 列表
aa = [10, 20]
bb = aa

print(id(aa)) # 2325297783432
print(id(bb)) # 2325297783432

aa.append(30)
print(bb) # [10, 20, 30], 列表为可变类型
print(id(aa)) # 2325297783432
print(id(bb)) # 2325297783432

5.1.3 lambda表达式:

如果?个函数有?个返回值,并且只有?句代码,可以使? lambda简化:

lambda 参数列表 : 表达式

lambda表达式的参数可有可?,函数的参数在lambda表达式中完全适?。

lambda函数能接收任何数量的参数但只能返回?个表达式的值

直接打印lambda表达式,输出的是此lambda的内存地址

示例:

# 函数
def fn1():
    return 200

# lambda表达式写法:
fn2 = lambda: 100

# lambda实现和运算:
lambda a, b: a + b

# 最简写法:
print((lambda a, b: a + b)(1, 2))

应用示例:

students = [
     {'name': 'TOM', 'age': 20},
     {'name': 'ROSE', 'age': 19},
     {'name': 'Jack', 'age': 22}
]
    
# 按name值升序排列
students.sort(key=lambda x: x['name'])
print(students)
    
# 按name值降序排列
students.sort(key=lambda x: x['name'], reverse=True)
print(students)
    
# 按age值升序排列
students.sort(key=lambda x: x['age'])
print(students)

**注意:**和Java的lambda表达式是不一样的

5.1.4 高阶函数

把函数作为参数传?,这样的函数称为?阶函数,?阶函数是函数式编程的体现。函数式编程就是指这种?度抽象的编程范式

示例:传入abs绝对值函数:

def sum_num(a, b, f):
    return f(a) + f(b)
result = sum_num(-1, 2, abs)
print(result) # 3

python内置的高阶函数:

5.1.4.1 map(func, Iterator)

map(func, lst),将传?的函数变量func作?到Iterator迭代器变量的每个元素中,并将结果组成迭代器(Python3)返回, 示例:计算 list1 序列中各个数字的2次?

list1 = [1, 2, 3, 4, 5]

def func(x):
    return x ** 2


result = map(func, list1)
# <map object at 0x0000013769653198>
print(result) 
# [1, 4, 9, 16, 25]
print(list(result)) 

5.1.4.2 reduce(func(x,y),lst)

reduce(func(x,y),lst),其中func必须有两个参数。每次func计算的结果(第一次运算是序列中前俩个元素)继续和序列的下?个元素做累积计算

示例:计算 list1 序列中各个数字的累加和

import functools

list1 = [1, 2, 3, 4, 5]

def func(a, b):
    return a + b


result = functools.reduce(func, list1)
print(result) # 15

5.1.4.3 fifilter(func, lst)

fifilter(func, lst)函数?于过滤序列, 过滤掉不符合条件(func)的元素, 返回?个 fifilter 对象,。如果要转换为列表,可以使? list() 来转换:

list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

def func(x):
    return x % 2 == 0


result = filter(func, list1)
# <filter object at 0x0000017AF9DC3198>
print(result)
# [2, 4, 6, 8, 10]
print(list(result)) 

5.2 文件IO

5.2.1 打开/关闭文件

使?open函数,可以打开?个已经存在的?件,或者创建?个新?件,语法如下:

open(name, mode)

返回的是 open 函数的?件对象

name:是要打开的?标?件名的字符串(可以包含?件所在的具体路径)。

mode:设置打开?件的模式(访问模式):只读、写?、追加等

mode取值:

在这里插入图片描述

关闭文件:

文件对象.close()

使用完文件最后在程序最后关闭文件释放内存

5.2.2 操作文件

5.2.2.1 写:write(‘内容’)

文件对象.write('内容')

5.2.2.2 读

  • read():
?件对象.read(num) 

num表示要从?件中读取的数据的?度(单位是字节),如果没有传?num,那么就表示读取?件中所有的数据

  • readlines()

    readlines可以按照?的?式把整个?件中的内容进??次性读取并且返回的是?个列表,其中每??

    的数据为?个元素

    无参数

  • readline()

    readline()?次读取??内容, 刚开始指针指向文件的第一行, 读取完之后指针往下移一行

  • seek(偏移量, 起始位置)

    作?:?来移动?件指针

    起始位置取值:

    0:?件开头

    1:当前位置

    2:?件结尾

可以通过这些读写操作实现文件复制,备份等

5.2.3 操作文件和文件夹

在Python中?件和?件夹的操作要借助os模块??的相关功能:

import os

# 重命名:
os.rename(?标?件名, 新?件名)
# 删除文件:
os.remove(?标?件名)
# 创建文件夹:
os.mkdir(?件夹名字)
# 删除文件夹:
os.rmdir(?件夹名字)
# 获取当前目录:
os.getcwd()
# 改变默认目录:
os.chdir(?录)
# 获取目录列表:
os.listdir(?录)

5.3 异常处理

python异常处理语法与Java不同

同时:python的异常可以套娃

try:
    可能发?错误1的代码
    try:
    	可能发?错误2的代码
    except:
        如果出现异常2执?的代码
except:
    如果出现异常1执?的代码

5.3.1 捕获指定异常:

try:
    可能发?错误的代码
except 异常类型:
    如果捕获到该异常类型执?的代码
    
    
try:
    print(num)
except NameError:
    print('有错误')

5.3.2 捕获多个异常:

当捕获多个异常时,可以把要捕获的异常类型的名字,放到except 后,并使?元组的?式进?书写

try:
    print(1/0)
except (NameError, ZeroDivisionError):
    print('有错误')

5.3.3 捕获异常描述信息

try:
    print(num)
except (NameError, ZeroDivisionError) as result:
    print(result)

5.3.4 捕获所有异常

Exception是所有程序异常类的?类

try:
    print(num)
except Exception as result:
    print(result)

5.3.5 异常else

else表示的是如果没有异常要执?的代码

try:
    print(1)
except Exception as result:
    print(result)
else:
    print('我是else,是没有异常的时候执?的代码')

5.3.6 异常finally

fifinally表示的是?论是否异常都要执?的代码, 和Java类似, 常用于释放资源:

try:
    f = open('test.txt', 'r')
except Exception as result:
    f = open('test.txt', 'w')
else:
    print('没有异常,真开?')
finally:
    f.close()

5.3.7 自定义异常:

在Python中,抛出?定义异常的语法为 raise 异常类对象

示例:

# ?定义异常类,继承Exception
class ShortInputError(Exception):
     def __init__(self, length, min_len):
         self.length = length
         self.min_len = min_len
         
         
 	# 设置抛出异常的描述信息
     def __str__(self):
     	return f'你输?的?度是{self.length}, 不能少于{self.min_len}个字符'
     	
     	
def main():
     try:
         con = input('请输?密码:')
         if len(con) < 3:
     		raise ShortInputError(len(con), 3)
     except Exception as result:
    	 print(result)
     else:
    	 print('密码已经输?完成')
    	 
    	 
main()

5.4 包

包将有联系的模块组织在?起,即放到同?个?件夹下,并且在这个?件夹创建?个名字为 init.py ?件,那么这个?件夹就称之为包, 这个?件控制着包的导??为

导入包分俩种:

5.4.1 导入包1

import 包名.模块名
from 包名 import 模块名

使用这种方法导入包只能通过包名.模块名.功能()调用

注意:

? 这里的导入和前面导入模块是不同的, 不能写*

? 但是可以使用as起别名, 但是哪怕是起别名, 如果名字冲突还是会报错

? 如果在相同包下, 则使用前面的导入模块语法, 使用这里的导入包语法也是会报错的

5.4.2 导入包2

**注意:**必须先在 __init__.py ?件中添加 __all__ = ['允许导入的模块名'] ,控制允许导?的模块列表,才可以使用这种方式:

from 包名 import *

像NumPy和sklearn等都是加上了这个

也就是说, 加上这个之后, from xxx import xxx就有俩种不同的含义了(从模块中导入方法, 从包中导入模块…)

6. 面向对象编程

什么是面向对象就不说了, 自己多敲点代码, 买本Java编程思想看吧

Python的面向对象也有的三大特性:封装, 继承, 多态

6.1 类

在python中不需要方法重载, 因为调用方法时参数是可以随意来的

6.1.1 经典方法定义类

经典方法是指类名后不跟():

class ClassName:
	...

6.1.2 新式方法定义类:

新式方法是指在类名后跟(类名), 表示继承:

class Prentice(objec):
    pass

在Python中,所有类默认继承object类,object类是顶级类或基类;其他?类叫做派?类

在子类中未定义构造函数,则创建子类对象默认调用父类中的构造函数

在子类中定义构造函数,则创建子类对象调用的是子类中的构造函数,不会主动去调父类的构造函数, 这和java不一样

但为了继承的时候父类的属性等能被初始化, 一般我们都会在子类__init__构造函数中调用父类构造函数(如果需要继承父类中的属性,则需要调用父类的构造函数)

注意:

  • 在python中支持多继承!!!当?个类有多个?类的时候,默认使?第?个?类的同名属性和?法,包括没写子类构造函数时也是默认调用第一个
  • 也因为python多继承加上经常儿孙满堂, 所以Python的继承结构异常复杂, 继承时的方法调用也异常恶心(出现了一个继承树…)
class Prentice(School, Master):
    pass

调用父类构造函数:

# 方式一:
    super(子类名, self).__init__(参数列表)

# 方式二:
    super().__init__(参数列表)

# 方式三:
    父类名.__init__(self, 参数列表)

# 调用父类函数一般也都是:
	super().函数名(参数列表)

注意:在单继承中,三种方式都可以使用;在多继承中,只能使用方式三

继承的特点
  1. 子类对象可以直接访问父类中未被私有化的属性和函数
  2. 父类的 __slots__ 属性对子类不起作用
  3. 父类对象不能访问子类中特有的属性和函数

6.1.2.1 重写

重写基本和Java一致

?类和?类具有同名属性和?法,默认使??类的同名属性和?法

6.1.3 self

python中的类中的方法经常有这么一个参数:self, self指的是调?该函数的对象, 相当于Java中的this

实例函数的形参列表第一个参数都是self,而普通函数则不是

6.1.4 封装

私有属性:只能在类的内部被直接访问,在对象属性的前面添加两个下划线表示是私有属性, 一般将私有属性写在构造函数__init__中, 直接写在类里也可以(一般将属性写在类下面或者__init__)

工作原理:一个属性一旦被私有化,在底层形成了 _类名__属性名 的属性名 ,但是不建议使用。私有化属性在底层的存在形式根据操作系统或者Python解释器的不同会有所差别,如果直接使用此种方式访问,违背了Python跨平台的特点

私有化之后在对外提供get/set方法, 一般命名:get_xx

同样的, 当类中的函数名前面加上__时表示私有函数, 只能被类内部调用

有用的一些__属性:__doc__, __all__(上面讲过), __slots__(下面讲), __dict__, __module__, __class__:

  1. __doc__

    表示类的描述信息,获取类中的文档注释(多行注释)

    类的描述信息类似于函数, 也是写在类体最前面的多行注释

    但是方法文档通过help(方法名)获取, 类文档通过这个属性获取

    不需要重写

  2. __dict__

    获取类或者对象的信息【属性和方法】,返回字典:

    也不需要重写

class MyClass(object):
    num = 10

    def __init__(self, m):
        self.m = m

    def show(self):
        pass

    @classmethod
    def func(cls):
        pass

    @staticmethod
    def test():
        pass


# 类名:类属性,构造函数,实例函数,类函数,静态函数
print(MyClass.__dict__)
m = MyClass(5)

# 对象:实例属性
print(m.__dict__)
  1. __module__

    获取当前操作的对象在哪个模块

    如果被操作的对象在当前模块,则获取的结果为__main__ ,如果被操作的对象在其他模块,则获取的结果为 模块名

    不需要重写

  2. __class__

    类似于type(xxx) ,返回当前对象的类型

6.1.5 魔法方法

__xx__()一般在python中称为魔法方法,都是具有特殊功能的函数, 一般都是从object那里重写来的

6.1.5.1 __new__,__init____del__()

工作原理:

  1. __new__:创建对象的时候首先自动调用__new__,它的作用就是创建实例,然后将该实例返回

  2. __init__:当实例创建完毕之后被调用的,然后通过__init__给实例设置初始值

  3. __new__先被调用,__init__后被调用,__new__的返回值(实例)将传递给__init__的第一个参数self,然后__init__给这个实例设置一些参数,__init__不需要返回值

  4. 严格意义上讲__init__才是构造方法, __new__不是

  5. 当对象被销毁的时候自动调用的函数,称为析构函数,析构函数为 __del__()

    当对象被定义为全局变量时,程序执行完毕,对象自动被销毁

    当对象被定义为局部变量,当指定的函数执行完毕,则对象随着会被自动销毁

    强制销毁对象,当对象被del时, 销毁对象执行析构函数 __del__()

6.1.5.2 __str__>__repr__

当使?print输出对象的时候,默认打印对象的内存地址。如果类定义了 __str__ ?法,那么就会打印从在这个?法中 return 的数据, 相当于Java中的重写toString()

__repr__ 方法 和 __str__ 方法功能类似,都是用来修改一个对象的默认打印内容。在打印一个对象时,如果没有重写 __str__ 方法,它会自动来查找 __repr__ 方法。如果这两个方法都没有,会直接打印这个对象的内存地址。如果两个方法都写了,选择 __str__ 方法

6.1.5.3 __eq__

__eq__ 方法如果不重写,默认比较依然是内存地址

6.1.5.4 汇总

运算符相关的一系列魔法方法:

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __eq__(self, other):  # 等于
        return self.name == other.name and self.age == other.age

    def __ne__(self, other):  # 不等于
        return self.age != other.age

    def __lt__(self, other):  # 小于
        return self.age < other.age
        # return self.age < other

    def __gt__(self, other):  # 大于
        return self.age > other.age

    def __le__(self, other):  # 小于等于
        return self.age <= other.age

    def __ge__(self, other):  # 大于等于
        return self.age >= other.age
    

算数运算符相关魔法方法:

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __add__(self, other):
        return self.age + other

    def __sub__(self, other):
        return self.age - other

    def __mul__(self, other):
        return self.age * other

    def __truediv__(self, other):
        return self.age / other

    def __mod__(self, other):
        return self.age % other

    def __pow__(self, power, modulo=None):
        return self.age ** power


s = Student('zhangsan', 18)
print(s + 1)  # 19
print(s - 2)  # 16
print(s * 2)  # 36
print(s / 5)  # 3.6
print(s % 5)  # 3
print(s ** 2)  # 324

类型转换相关魔法方法:

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __int__(self):
        return self.age

    def __float__(self):
        return self.age * 1.0

    def __str__(self):
        return self.name

    def __bool__(self):
        return self.age > 18


s = Student('zhangsan', 18)
print(int(s))  # 18
print(float(s))  # 18.0
print(str(s))  # zhangsan
print(bool(s))  # False

6.2 对象

dir()函数可以查看对象内的所有的属性和方法

6.2.1 创建对象:

对象名 = 类名()

调用类中的函数实, 如果通过类名调(必须手动传self):

类名.方法名(self, 参数)

# 例如:
p = Person()
Person.eat(p,'吃饭')

如果通过对象调, 则不用传self,会自动传入:

p.eat('吃饭')

6.2.2 对象属性

属性即成员变量, 在python中的对象属性即可以在类中添加获取, 也可以在类外面添加获取

在类外面获取对象属性(和Java一样):

对象名.属性

在类外面添加属性(Java没有)

对象名.属性 =

但是这种方法绑定的属性的数量没有上限,绑定的属性的名称没有限制,在实际项目开发中,需要进行限制绑定

限制绑定方法:

在类中增加一个属性:__slots__=(属性1, 属性2..)(俩个_)

这样子在类外增加属性时, 如果属性名在__slots__中没有, 则会报错

注意:

  • __slots__中定义的属性仅对当前类的实例起作用,对继承的子类实例是不起作用
  • 如果子类本身也有 __slots__ 属性,子类的属性就是自身的 __slots__ 加上父类的 __slots__

同时在类里面设置的属性相当于静态的, 是类所有的, 所有的对象共享同一个(类属性只能通过类对象修改,不能通过实例对象修改,如果通过实例对象修改类属性,表示的是创建了?个实例属性:

class A:
    a = 1

    def __init__(self, b):
        print("A初始化")
        self.a = b


a = A('a')
# a
print(a.a)

b = A('b')
# b
print(b.a)
# a
print(a.a)

但是在类外设置的属性就是属于当前对象的

在类里面获取属性(相当于java中的this.属性, 但是Java的this可以省略, python不可以省略self):

self.属性

6.3 多态

不同的子类调用相同的父类方法,产生不同的执行结果,可以增加代码的外部灵活度。多态是以继承和重写父类方法为前提的,它是一种调用方法的技巧,不会影响到类的内部设计

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 20:45:38  更:2022-03-21 20:48:32 
 
开发: 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/29 12:53:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计