Python基础语法学习笔记V1
python
python安装方法
http://www.python.org
python的使用
-
python的交互式环境进入,win10中采用win+R快捷键进入运行窗口,输入
python
进入python。exit( )
或者quit()
退出交互式环境。 -
申明一个.py文件,即可保存python代码。打开命令行的提示符,进入到文件所在的路径,直接输入
python 文件名.py
注释
单行注释
python的注释是ctrl+/,或者是用 #
多行注释
''' 多行注释采用的是三个多引号 '''
python的IDE
使用的python的IDE为PyCharm
第一章
变量
python是一门强类型语言,不需要制定数据类型,给变量赋值的同时确定变量的数据类型
凡事皆对象
变量的定义
a = 10;
a = '小李同学';
print(a);
# 变量名 = 数据
变量的数据类型:
graph LR; A(数据类型) --> B(数字 num); A --> C(字符串 str); A --> D(字典 dict); A --> E(元祖 Tuple); A --> F(列表 list); B --> B1(int 有符号整型); B --> B2(long 长整型 Python3中取消); B --> B3(float 浮点); B --> B4(complex 复数 ); B --> B5(布尔 bool);#查询数据类型函数
b = type(a);
#元祖类型tuple
b = ();
#列表类型list
b = [];
#字典类型dict
b = {};
变量命名规则
-
变量必须以字母或者下划线开始
-
变量不能是数字或者其他符号开始
-
变量可以区分大小写
-
python中的关键字不能作为变量名
运算符
算数运算符
算数运算符 | 作用描述 | 示例 |
---|---|---|
+加 | 算数加 | 5 + 3 = 8 |
-减 | 算数减 | 5 - 3 = 2 |
*乘 | 算数乘 | 5 * 3 = 15 |
**指数 | 左边是底数,右边是指数 | 5 ** 3 = 125 |
%余数 | 求余数 | 5 % 3 = 2 |
/除法 | 结果包含小数(会自动转换为float) | 5 / 2 = 2.5 |
// 地板除 | 结果忽略小数 | 5//2 = 2 |
比较运算符
比较运算符 | 名称 |
---|---|
== | 等于 |
!= | 不等于 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
逻辑运算符
逻辑运算符 | 描述 |
---|---|
and | 与 |
or | 或 |
not | 非 |
位运算符
位运算符 | 描述 |
---|---|
& | 按位与 |
| | 按位或 |
^ | 按位异或 |
~ | 按位取反 |
<< | 左移位 |
>> | 右移位 |
print(12&8) #结果是8 12:1100 8:1000 结果为1000 8
print(4|8) #结果是12
print(-8>>2) #结果是-2
赋值运算符
赋值运算 | 描述 |
---|---|
= | 右边的值赋给左边 |
+= | c += a; c = c + a; |
-= | c -= a; c = c - a; |
*= | c *= a; c = c * a; |
/= | c /= a; c = c / a; |
%= | c %= a; c = c % a; |
**= | c **= a; c = c ** a; |
//= | c //= a; c = c // a; |
输入和输出
通过使用%
占位符号,\n
换行。
name = 'zhang';
class =' 一(1)班';
print('我的名字是%s : 来自【%s】'%(name,class));
格式符号 | 转换 |
---|---|
%c | 字符 |
%s | 字符串 |
%i | 有符号十进制整数 |
%d | 有符号十进制整数 |
%u | 无符号十进制整数 |
%o | 八进制整数 |
%x | 十六进制整数 |
%e | 索引符号 |
%E | 索引符号 |
%f | 浮点数 |
个数画输出的其他方式 .format()
name = 'zhang';
class =' 一(1)班';
print('我的名字是:{}, 来自【{}】'.format(name,class));
函数input
可以获得输入,获得的为字符串。
name = input('请输入:');
print(print(3))
#结果为:
#3
#None
上例说明:
python是编译一部分执行一部分,再编译一部分执行一部分
每次执行一部分都会得到一个对象,执行print(3)
语句的结果为None
None
也是一个对象(object),对象类型是NoneType
输出中文也可以使用Unicode的方法,在知道中文字对应的16进制代码(也可以使用函数ord()
获得)
print('\u5317') #北
print('\u5317',end=`-->`) #北
print
函数是以回车结束,中间是空格,可以通过在末尾加sep=
和end=
进行修改,也可以加file=
修改打印的文件
def print(self, *args, sep=' ', end='\n', file=None): # known special case of print
"""
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.
"""
pass
第二章
流程控制
python 中蓝色字体的对齐排版是非常重要的
流程:代码执行的顺序
graph LR; A(流程)-->B1(顺序流程) B1 --> C0(程序默认的流程) A -->B2(选择流程) B2 -->C1(单分支) B2 -->C2(双分支) B2 -->C3(多分支) A -->B3(循环流程)if的使用
if 条件表达式:
python代码
else:
python代码
if 条件表达式:
python代码
elif:
python代码
elif:
python代码
else:
python代码
实例
score = 60
if (score <= 60):
print('成绩不及格')
pass #pass代表空语句,表示暂时不处理,作用是使代码看起来更完整,常用于填坑
print('结束')
score = 60
if (score <= 60):
print('成绩不及格')
pass #pass代表空语句,表示暂时不处理,作用是使代码看起来更完整,常用于填坑
else:
print('成绩及格')
pass
print('结束')
注意在C语言中是没有
:
的,注意区别。
//C 语言
int score = 60;
if (score <= 60){
printf("成绩不及格\n");
}
else{
printf("成绩及格\n");
}
printf("结束\n");
循环流程 while() for()
while(条件表达式):
python代码
for ...(变量) in ...(可迭代集合对象)
python代码
注意在C语言中是没有
:
的,注意区别。python中的缩进是有语法意义的
示例1:输出1到10
index = 1
while index <= 10:
print(index)
index += 1
pass;
//C 语言
int index = 1;
while (index <= 10){
printf("%d\n",index);
index += 1;
}
示例2:输出三角形
row = 1
while(row <= 7):
j = 1
while(j <= row):
print('*',end=' ')#将换行符修改为空格
j += 1
pass
print('\n')#两个换行符因为自带一个换行符
row += 1
pass
//C语言
int row = 1;
while(row <= 7){
int j = 1;
while(j <= row){
printf("* ");
j += 1;
}
printf("\n\n ");
row += 1;
}
for循环示例
tags = '小李同学'; #字符串是字符类型的集合
for item in tags:
print(item);
pass
#range 此函数可以生产一个数据集合列表
#range(开始:结束:步长) 步长不能为0 注意和MATLAB去别 MATLAB是(开始:步长:结束)
a = range(1,101,1); #数据是左包含 右不包含 此数据为1到100
for data in a:
if (data % 3) == 0:
print(data, end = ' ');
pass
pass
//C语言
for (int data = 1; data < 100; data++){
if ((data % 3) == 0)
printf("%d ", data);
}
break
中断结束,仅能在循环中使用
continue
跳过此次循环,进入下次循环仅能在循环中使用
实例 剪刀 石头 布
import random;
while(1):
person = int(input('请出拳[0:剪刀 1:石头 2:布]:'));
computer = random.randint(0, 2);
print(computer);
if (person - computer == 1) or (person - computer == -2):
print('you win');
pass;
elif (person == computer):
print('平手');
pass;
else:
print('you lose');
pass;
第三章
序列操作
2021年6月9日 day3 class3
序列:一组按顺序排列的值【数据集合】
在python中存在三种内置的序列类型:字符串 列表 和 元组 字典不属于序列的范围
序列的优点:可以支持索引和切片的操作
序列的特征:第一个正索引为0,指向的是左端,第一个索引为负数的时候,指向的是右端。
字符串string''
切片:截取字符串中的一段内容,是属于字符串的高级特性。
切片使用语法:[起始下标:结束下标:步长]切片截取的内容不包含结束下标对应的数据,步长指的是隔几个下标获取一个字符,步长默认为1。
注意切片操作不会出现越界的情况,是左闭右开。
语法结构:[start: end: ?step]
函数名 | ||||
---|---|---|---|---|
capitalize() | isalnum() | islower | swapcase | title() |
endswith/startwith() | isalpha | join | Istrip/rstrip/strip | replase(old,new,count=None) |
find() | isdigit() | lower/uper | split | count() |
部分函数解析:
a.index('a') 功能类似于find() : 检测字符串中是否包含子字符串,返回的是下标值(从0开始),index若没有找到对应的数据便会报异常,find是返回(-1)
Test = 'python';
#print(type(Test));
print('获取第一个字符%s'%Test[0])
for item in Test:
print(item,end=' ')
pass
name = 'peter'
print('首字母大写%s'%name.capitalize()); #首字母大写 输出为Peter
name = ' hello ';
b = name.strip(); #去除空格
c = name.lstrip(); #去除左空格
d = name.rstrip(); #去除右边的空格
print(b);
f = name; #复制操作,此时name和f完全一致
print('f的id地址%d'%id(f));
print('name的id地址%d'%id(name)); #两个的id是相同的 f重新赋值后,地址发生变化
dataStr = ' I love you';
m = dataStr.find('u'); #查找目标值在目标值中的位置,返回位置值(从0开始),仅查找一个,若不存在,则返回-1
print(m);
print(dataStr.startswith('I')); #判断是否以I开头,返回bool值true 或者false endswith类似
print(dataStr.lower()) #全部转换为小写
print(dataStr.upper()) #全部转换为大写
列表list []
特点1、支持增删改查
2.列表中的数据是可以变化的【数据项可以变化,但是地址不变】
3.用中括号表示列表类型,数据项中间用逗号分割,数据项是任何类型的数据
4.支持切片操作
函数名 | 功能描述 |
---|---|
append | 在列表后面追加元素 |
count | 统计元素出现的次数 |
exend | 拓展,相当于批量添加 |
index | 获取指定元素索引号 |
insert | 在指定位置插入元素 |
pop | 删除最后一个元素 |
remove | 移除左边找到的第一个元素 |
reverse | 反转列表 |
sort | 列表排序 |
li=[1,2,2,'小李同学'];
print(len(li)); #结果是4个数据
list=[1,2,3,'abcd',343,234,True];
print(list); #输出打印对象
print(list[3]); #输出第3个元素 返回的是元素
print(list[0:3:1]); #输出0到3个元素 返回的是列表
print(list*2); #输出多次列表中的数据
#增加
list.append([2,3,4,'love']);
#插入
list.insert(1,'love'); #需要指定位置
#强制转换
rsdata = list(range(3));
list.extend(rsdata); #批量添加,拓展 等效于list.extend([0,1,2]);
print(list);
#修改
list[0] = 'peter';
list[0] = 234.45;
#删除
del list[0]; #通过del删除列表元素
del list[2:4]; #通过切片实现批量操作
list.remove('love'); #移除指定元素,是元素
list.pop(0); #移除的是指定位置的元素
list.index(a,ranga,rangb); #在ranga 到 rangb 中查找a
元组tuple ()
元组是一种不可变的序列,创建后不能做任何修改,但是可以对元组中的列表元素进行修改
用()
创建元组,数据项可以是任何类型,用,
分割,当元组中只有一个元素时也要加上,
否则编译器会当做整型处理,同样可以支持切片操作。
无法进行增删改,仅可以进行查询
tupleA = ('abcd',2,3,4,True,'love',[2,3,4]); #元组创建 tuple
#元组的查询
for item in tupleA:
print(item,end=' ');
pass
print(tupleA[0:3]); #使用切片取值
print(tupleA[-3:-1:1]); #倒着取下标 -1是最右边的数据
print(tupleA[-2:-4:-1]); #倒着取下标
tupleA[6][0] = 23; #可以对元组中的列表修改
c = tupleA.count(2);#统计元素出现的次数
字典dict{}
- 字典不是序列,不能采用切片操作,没有下标的概念,是内置的高级数据类型
- 是有 键值对 组成的集合,通常使用键值对访问数据
- 可以存储任意对象,字典是以键值对的形式创建的{'key':'value'}每个键值对用逗号
,
隔开 - 键不能重复,且是不可变的,键是唯一的。值可以是任意的类型
- 每个键必定是惟一的,如果存在重复的键,后者会覆盖前者
常用的键的操作
修改元素、新增元素、删除元素、统计个数,获取值:keys、获取值:values,获取键值对、删除指定键
#添加字典数据
dictA = {};
dictA['name'] = '小李同学' #key :value
dictA['age'] = 25;
dictA['pos'] = 'doctor'
print(dictA)
dictB = {'name':'zhangxf','school':'CQU'}
print(dictB) #输出完整的字典
print(len(dictB))
print(dictA['name']) #读取字典中的值即查找 通过键获取值
dictA['name'] = '小李同学'
print(dictA)
# 获取所有的键
print(dictA.keys())
# 获取所有的值
print(dictA.values())
# 获取所有的数据项
print(dictA.items())
for item1,item2 in dictA.items():
print('%s == %s'%(item1,item2))
pass
# 输出结果
# name == zhangxf
# age == 25
# pos == stu
#修改字典
dictA.update({'name':'xiaol'})
print(dictA)
#删除操作 通过键进行操作
del dictA['name']
print(dictA)
dictA.pop('age')
print(dictA)
#排序操作
print( sorted(dictA.items(),key=lambda d:d[0]) )
# d:d[0]代表的是按照key排序,d:d[1]代表的是按照value 排序,key=lambda d:d[]是固定用法
共有方法
+
合并
strA = '人生苦短'
strB = '还好有你'
print(strA+strB)
#结果:人生苦短还好有你
#字符串合并和列表合并相同
*
复制 可以复制多倍
strA = '人生苦短'
print(strA*3)
#结果:人生苦短人生苦短人生苦短
in
对象是否存在
strA = '人生苦短'
print('生' in strA)
#结果:True 是一个bool类型的数据
print('我' in strA)
#结果:False
字符串和列表相同,对于字典来说是判断 键是否存在于字典中。
第四章
函数
函数主要有:函数参数(传参,调用,不定长参数)和返回值
函数定义
函数是一系列Python语句的组合,可以在程序中运行一次或者多次,可以完成具体的独立功能。
函数的意思:代码的复用最大化以及最小化冗余代码
def + 关键字 + 小括号 + 冒号 + 换行缩进 + 代码块
定义一个函数
def 函数名():
? 代码块
函数调用:函数名加()即可调用,在函数调用之前,必须先定义,函数的第一行是默认的备注信息(三个单引号)
# 函数的定义
def printInfo():
'''
打印个人信息,是对个人信息的组合
:return:
'''
#函数的代码块
print('小张的身高是:%f' % 1.77)
print('小张的体重是:%d' % 160)
print('小张的爱好是:%s' % '打篮球')
print('小张的专业是:%s' % '电气工程')
pass
#函数的调用
printInfo()
函数的参数
def printInfo(name, height, weight, hobby, pro):
'''
打印个人信息,是对个人信息的组合
:return:
'''
#函数的代码块
print('%s的身高是:%f' %(name,height))
print('%s的体重是:%d' % (name,weight))
print('%s的爱好是:%s' %(name,hobby))
print('%s的专业是:%s' % (name, pro))
pass
#调用函数
printInfo('小李',158,100,'打游戏','医生')
参数的分类:
必选参数,默认参数[缺省参数],可选参数,关键字参数
参数:函数为了实现某项特定的功能,进而为了得到实现功能所需要的数据,即为了得到外部的数据
1 必选参数 在函数调用的时候,是必须进行赋值的。
def sum(a,b):
sum = a + b
return sum
2 默认参数[缺省参数]
缺省参数,始终存在于参数的最后,因为函数调用的时候
def sum1(a = 20, b = 30):
sum = a + b
print(sum)
pass
sum1() #结果为50
sum1(10) #结果为40 默认参数尽量放在后面,因为若后面参数是必选参数,此种情况会报错
sum1(10,10) #结果为20
3 可选参数*
,即可以变化的参数【不定长参数】当参数的个数不确定时候使用,比较灵活 形式是元组
def getComputer(*args):
'''
计算累加和
:param args: 可变长的参数类型
:return:
'''
# print(args)
result = 0
for item in args:
result += item
pass
print(result)
pass
getComputer(1,2,3,5,6) #结果是17
getComputer(1,2,3) #结果是6
4 关键字参数 **
是一个可变参数,在函数体内是字典类型,key必须是一个字符串
def keyFunc(**kwargs):
print(kwargs)
pass
#调用
# keyFunc(1,23,4) #错误使用方法
dictA = {'name':'zhang','age':'25'}
keyFunc(**dictA)
keyFunc(name = 'peter',age = 26,pos = 'doc')
keyFunc() #不传也可以
在混合调用时,可选参数必须放到关键字参数之前
可选参数接受的数据是一个元组
关键字参数接受的是一个字典
函数的返回值
概念:函数执行完成后会返回一个对象,如果在函数的内部有return,就可以返回实际的值,否则返回None
类型:可以返回任意类型,返回值类型应该取决于return后面的类型
用途:给调用方返回数据
在一个函数体内可以出现多个return关键字,但是只能返回其中的一个
如果在一个函数体内执行了return就意味着,我们的函数就退出了,return后面的代码语句将不再执行
函数的嵌套
def fun1():
print('---------start1-----------')
print('---------函数1-----------')
print('---------end1-----------')
pass
def fun2():
print('---------start2-----------')
fun1()
print('---------end2-----------')
pass
fun2()
#结果
---------start2-----------
---------start1-----------
---------函数1-----------
---------end1-----------
---------end2-----------
函数的分类
有参数无返回值 :一般是计算型,需要参数,最终需要计算的结果
有参数有返回值 :一般用于无需返回值的参数设置
无参数有返回值 :一般多用在数据采集中,比如获取系统信息,获取CPU信息等
无参数无返回值 :一般用于提示信息的答应
exercise
写函数,接收n个数字,求这些参数数字的和
def CalcuSum(*num):
result = 0
for item in num:
result += item
pass
return result
pass
print(CalcuSum(1,2,3,4,5))
写函数,找出传入的列表或元组的奇数位对应的元素,并返回一个新的列表
def process_Func(con):
listNew = []
index = 1;
for i in con:
if (index%2 == 1): #判断奇数位
listNew.append(i)
pass
index += 1
pass
return listNew
pass
print(process_Func([1,2,3,4,5]))
写函数,检查传入字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。PS:字典中的value只能是字符串或者列表
def dictParamFun(dictParam):
'''
处理字典类型的数据
:return:
'''
result = {} #空字典
for key,value in dictParam.items():
if len(value) > 2:
result[key] = value[:2]
pass
else:
result[key] = value
pass
pass
return result
pass
# 函数调用
dicObj = {'name':'zhang','hobby':['唱歌','dance','运动'],'pro':'stu'}
print(dictParamFun(dicObj))
第五章
变量
在python中变量是一种标签,给需要赋值的对象贴标签;对比C语言,可以理解为指针
a = 'hello'
b = 'hello'
这两个hello
是否是一个hello
?
这是一个hello,因为变量a
和b
在内存中的地址是相同的
在python中=
是一个捆绑的过程
a = print
a(3)
#这种方式也可以实现print(3)的功能
局部变量
在函数内部定义的变量,作用范围仅仅是在函数内部进行使用。
不同的函数可以定义相同的局部变量,但是这些局部变量直接不会互相影响。
作用:为了临时的保存数据,需要在函数中定义来进行
全局变量
作用的范围是整个文件
当全局变量和局部变量命名重复时,程序优先执行使用函数内部定义的变量【局部变量】
name = 'zhang'
def printinfo():
name = 'xiaoli'
print(name)
pass
def TestInfo():
print(name)
pass
printinfo()
TestInfo()
#结果是
xiaoli
zhang
全局变量的修改
鉴于以上在函数内部会将和全局变量相同名称的变量默认为函数内部的局部变量,因此要在函数中修改全局变量,必须要在变量前加关键字global
name = 'zhang'
print(name)
def changeGlobal():
global name
name = 'xiaoli'
pass
changeGlobal()
print(name)
引用
核心思想:万物皆对象
1、在函数调用的时候,实参传递的就是对象的引用
2、了解了原理之后,就可以更好的去把控,在函数内部的处理是否会影响到函数外部的数据变化
在python中,值是靠引用来传递的,可以用id()查看一个对象的引用是否相同,id是值保存在内存中那块内存地址的标识。
变量只是对变量地址的引用,新的值会有新的地址
匿名函数
python中使用lambda
关键字创建匿名函数,所谓匿名即这个函数没有名字不用def
关键字穿件标准的函数。
标准:lamdba 参数1,参数2,参数3:执行代码语句
使用lambda表达式计算两个数之和:
test = lambda x,y:x+y
test(1,3)
test(4,5)
若是普通函数,则
def test(x,y)
return x+y
pass
特点
使用lambda关键字创建函数
函数没有名字
匿名函数冒号后面的表达式有且只有一个,注意是表达式,而不是语句
匿名函数自带return,而这个return的结果就是表达式计算之后的结果
通过变量调用匿名函数(类似C语言中的宏定义)
functest = lambda x,y:x if x > y else y #三目运算符
print(functest(12,2))
缺陷:只能是单个表达式,不是一个代码块,lambda仅仅是为了简单的函数场景,复杂逻辑实现不了,必须使用def
递归函数
在函数内部调用自己
递归函数必须有清楚的结束条件,即边界条件
优点:逻辑简单,定义简单
缺点:容易导致堆栈溢出,内存资源紧张
递归案例 模拟实现 树形结构的遍历
import os #引入文件操作模块
def findFile(file_path):
listRs = os.listdir(file_path) #得到该路径下所有的文件夹
for fileitem in listRs:
full_path = os.path.join(file_path,fileitem) #获取完整的文件路径
if os.path.isdir(full_path): #判断是否是文件夹?
findFile(full_path)
pass
else:
print(fileitem)
pass
pass
else:
return
pass
#调用问价路径
print( findFile('F:\\learningnotes\\00leetcode') )
第六章
内置函数
python中自带的函数
所有内置函数官网文档:
http://docs.python.org/3/library/functions.html 文档中有函数的详细说明
Built-in Functions | ||||
---|---|---|---|---|
abs() |
delattr() |
hash() |
memoryview() |
set() |
all() |
dict() |
help() |
min() |
setattr() |
any() |
dir() |
hex() |
next() |
slice() |
ascii() |
divmod() |
id() |
object() |
sorted() |
bin() |
enumerate() |
input() |
oct() |
staticmethod() |
bool() |
eval() |
int() |
open() |
str() |
breakpoint() |
exec() |
isinstance() |
ord() |
sum() |
bytearray() |
filter() |
issubclass() |
pow() |
super() |
bytes() |
float() |
iter() |
print() |
tuple() |
callable() |
format() |
len() |
property() |
type() |
chr() |
frozenset() |
list() |
range() |
vars() |
classmethod() |
getattr() |
locals() |
repr() |
zip() |
compile() |
globals() |
map() |
reversed() |
__import__() |
complex() |
hasattr() |
max() |
round() |
abs()
绝对值函数
#绝对值
abs(-34) #结果是34
round()
函数
描述:对浮点数进行近似取值,保留几位小数
语法:round(x,n)
参数:x--数值表达式 n--保留位数
返回值:返回浮点数x的近似值
注意:这里不完全是按照四舍五入或者四舍六入五成双来进行取值,取值和python的版本有关,还和浮点数的精度有关
round(2.6) 3
round(2.4) 2
round(3.66,1) 3.7
pow()
求次方 同**
max()
最大值 参数可以是序列,元组,列表
min()
最小值
sum()
对系列进行求和计算
eval()
执行字符串表达式,并返回表达式的值
语法 eval(expression, [ globals, [ locals ] ] )
expression - 表达式
globals - 变量作用域,全局变量,如果被提供,则必须是一个字典
locals - 变量作用域,局部变量,如果被提供,可以是任何映射对象
返回值:返回表达式计算结果
a,b,c = 1,2,3
eval('a+b+c') #结果为6 这是动态执行函数
类型转换函数
chr()
数字转字符 按照ASCII码进行的
chr(65) #结果为A
chr(66) #结果为B
bin()
十进制转为二进制
hex()
十进制转为十六进制
list()
将元组转换为列表
tuple()
将列表转为元组
dict()
创建字典
#创建字典
dic = dict()
print(type(dic))
dic['name'] = 'xiaoli'
dic['age'] = 18
print(dic)
dic = dict(name = 'xiaoli',age = 18)
print(dic)
bytes() 转换为字节数组
返回一个新字节数组,这个数组里的元素时可变的,并且每个元素的值范围:0 <= x < 256
需要指定编码方式
print(bytes('我喜欢python',encoding = 'utf-8'))
#结果:
b'\xe6\x88\x91\xe5\x96\x9c\xe6\xac\xa2python'
序列操作函数
all( ) 函数用于判断给定的可迭代参数的所有元素是否都为TRUE,如果是返回TRUE,否则返回False元素,除了是0、空、FALSE外都是TRUE
对象是元组或者列表
li = [1,2,3]
print(all(li)) #True
li = [1,2,3,4,5,0]
print(all(li)) #False
空元素和空列表返回值也是TRUE
any() 函数用于判断给定的可迭代参数的所有元素是否都为FALSE,返回FALSE,如果有一个是True,则是True
类似于逻辑运算符中的OR的运用,有一个为真则结果为真
all() 函数类似于逻辑运算符中的AND运用,有一个为假则为假
sort函数和sorted
sort函数是应用在list上的方法,sorted可以对所有的可迭代的对象进行使用。
sort的返回值是对已经存在的列表进行的操作,和内建函数sorted方法返回的是一个新的list。而不是原来基础上的进行的操作。
语法:sorted(iterable,[cmp],[key],[reverse])
iterable 迭代对象
cmp 比较的函数,这个具有两个参数,参数的值都是从可迭代对象中取出,此函数必须遵循的规则为,大于则返回1,小于则返回-1
key 主要用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序
reverse 排序规则,reverse = true 降序,reverse = false 升序
返回值:重新排列的列表
print( sorted([1,2,3,5,8,6,5,43])) #结果为[1, 2, 3, 5, 5, 6, 8, 43]
print( sorted([1,2,3,5,8,6,5,43],reverse=True)) #结果为[43, 8, 6, 5, 5, 3, 2, 1]
range() 创建一个整数列表,一般用在for循环中
语法:range(start,stop,step) 左闭右开
也可以只有一个stop,如range(5) 等效于 range(0,5)等效于range(0,5,1)
zip()函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。如果各个迭代器的元素个数不一致,则返回列表长度与最短的相同,利用*号操作符,可以将元组解压为列表。
s1 = ['a','b','c']
s2 = ['你','我','他']
print(zip(s1)) #结果是
print( list(zip(s1)) ) #结果是[('a',), ('b',), ('c',)]
print( list(zip(s1,s2)) ) #结果为[('a', '你'), ('b', '我'), ('c', '他')]
图书管理示例:
def printBookInfo():
books = [] #存储图书信息
id = input('请输出图书编号:每项之间是空格分隔')
bookname = input('请输入书名:每项之间是空格分隔')
bookpos = input('请输入位置:每项之间是空格分隔')
idlist = id.split(' ')
namelist = bookname.split(' ')
poslist = bookpos.split(' ')
bookInfo = zip(idlist,namelist,poslist)
for bookitem in bookInfo:
'''
遍历图书信息,进行存储
'''
dictInfo = {'编号':bookitem[0],'书名':bookitem[1],'位置':bookitem[2]}
books.append(dictInfo) #将字典对象添加到list容器中
pass
for item in books:
print(item)
pass
print(books)
pass
printBookInfo()
#结果:
#请输出图书编号:每项之间是空格分隔1 2 3
#请输入书名:每项之间是空格分隔python C C#
#请输入位置:每项之间是空格分隔A1 A2 A3
#{'编号': '1', '书名': 'python', '位置': 'A1'}
#{'编号': '2', '书名': 'C', '位置': 'A2'}
#{'编号': '3', '书名': 'C#', '位置': 'A3'}
#[{'编号': '1', '书名': 'python', '位置': 'A1'}, {'编号': '2', '书名': 'C', '位置': 'A2'}, #{'编号': '3', '书名': 'C#', '位置': 'A3'}]
enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在for循环当中
语法:enumerate(sequence,[start = 0])
参数:sequence 一个序列
? start--下标的其实位置
listobj = ['a','b','c']
for item in enumerate(listobj):
print(item)
pass
#结果: 结果是元组
#(0, 'a')
#(1, 'b')
#(2, 'c')
for item in enumerate(listobj,5):
print(item)
pass
#结果: 结果是元组
#(5, 'a')
#(6, 'b')
#(7, 'c')
dicObj = {}
dicObj['name'] = 'zhangxf'
dicObj['hobby'] = 'lalala'
dicObj['pro'] = 'stu'
for item in enumerate(dicObj):
print(item)
pass
#结果:
#(0, 'name')
#(1, 'hobby')
#(2, 'pro')
set(集合) 也是python中的一种数据类型{}
set1={'1','2'}
不支持索引和切片 类似于字典,但是只有key 没有value
add 添加 clear 清楚 difference(a,b) a中存在 b中不存在
intersection 取交集
union 取并集
pop 就是从集合中拿数据,并且拿了之后就删除了
discard 指定移除数据
update 更新数据 需要两个集合,在原来的基础上将两个结合合并,和union差不多。
第七章
面向对象编程
面向过程:根据业务逻辑从上到下写代码
函数式:将某功能代码封装到函数中,日后便无需重复编写,即调用代码
面向对象编程:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的书写过程。
oop(object oriented programming)
面向过程:在思考问题的时候,首先分析,如何按照步骤去实现,然后将问题解决拆解成若干个步骤,并将这些步骤对应成方法一步一步的最终完成功能。
面向对象:关注的是设计的思维,关注点是谁来做。
类和对象
类和对象是面向对象编程中重要的概念
类就是一个模板,模板里可以包含对个函数,函数里实现一些功能
对象则是根据模板创建的示例,通过实例对象可以执行类中的函数
类是具有一组相似或者相同特征【属性】和行为【方法】的一系列对象的结果
对象是实实在在的东西,是类的具象化和实例化
类的组成部分
1 类名
2 类的属性 一组数据
3 类的方法 允许对类进行操作的方法
举例 :创建一个类:人
事物名称(类名):人
属性:身高、年龄
方法:吃、跑
定义类和对象
结构:class 类名:
? 属性
? 方法
class Person:
name = '小明' #人的特征
age = 20
#方法
def eat(self):
#函数语法
pass
def run(self)
pass
对象 结构
对象名 = 类名()
xm = Person()
xm.eat() #调用函数
xm.run() #调用函数
实例方法
在类的内部,使用def关键字可以定义一个实例方法,与一般函数定义不同,类方法必须包含参数self,且作为第一个参数。
类属性
在类的内部定义的变量,归属于类所有,在方法外面的属性称之为类属性
实例属性
定义在方法里面的使用self引用的属性称之为实例属性,归属于实例对象所有
_init_(self)
方法,初始化方法,实例化对象的时候自动调用,完成一些初始化设置
凡是由双下划线组成的函数,均是python内部的,魔术方法
_init_
可以传参
class Person:
def __init__(self,name,sex,age):
self.name = name
self.sex = sex
self.age = age
pass
pass
zp = Person('zp','男',18)
print(zp.name,zp.age,zp.sex)
初始化函数是python自带的内置函数,特点是两边用双下划线包裹的,函数的作用为一个初始化的方法,主要是用来设置定义实例属性和初始化数据的,在创建对象的时候自动调用,不用手动调用
利用传参的机制,可以使得功能更加强大方便。
self
self和对象指向的是同一个内存地址,可以认为self即为对象的引用
魔法方法
在python内部,会有一些内置好的特定的方法,方法名是:“__xxx__
”,在进行特定的操作时会自动被调用,这些方法称之为魔法方法。
__init__
初始化一个类,在创建对象的时候为其赋值时使用
__Str__
在将对象转换为字符串
__new__
创建并返回一个实例对象
__class__
获得已知对象的类
__del__
对象在运行程序结束后进行对象销毁的时候调用这个方法,并释放资源
1 __Str__
方法,在打印对象的时候,会执行此实例方法,返回一个字符串
在print的时候调用
2__new__
创建并返回一个实例对象
案例:决战紫禁之巅
-
属性:
- name 玩家的名字
- blood玩家血量
-
方法:
- tong() 捅对方一刀,对方掉血10滴
- kanren()砍对方一刀,对方掉15滴
- chiyao()吃一颗药丸,补血10滴
_str_
打印玩家状态
#第一步 需要先去定义一个类【角色类】
class Role:
def __init__(self,name,hp):
"""
构造初始化函数
:param name 角色名
:param hp 血量
"""
self.name = name
self.hp = hp
pass
def tong(self,enemy):
"""
捅一刀
:param enemy: 敌人
:return:
"""
enemy.hp -= 10 #敌人少10滴血
info = '[%s]捅了[%s]一刀'%(self.name,enemy.name)
print(info)
pass
def kanren(self, enemy):
enemy.hp -= 15 #敌人少15滴血
info = '[%s]砍了[%s]一刀'%(self.name,enemy.name)
print(info)
pass
def chiyao(self):
self.hp += 10 #敌人少15滴血
info = '[%s]吃了一颗补血药,增加了10滴血'%(self.name)
print(info)
pass
def __str__(self):
return '[%s]的血量还剩下%d'%(self.name,self.hp)
pass
#创建两个实例化对象
zhang = Role('西门吹雪',100)
ygc = Role('叶孤城',100)
while True:
if zhang.hp <= 0 or ygc.hp <= 0:
break
pass
zhang.tong(ygc) #西门吹雪捅了叶孤城一刀
print(zhang)
print(ygc)
print('************************************')
ygc.kanren(zhang) #西门吹雪被叶孤城砍了一刀
print(zhang)
print(ygc)
print('************************************')
ygc.tong(zhang)
print(zhang)
print(ygc)
print('************************************')
zhang.chiyao()
print(zhang)
print(ygc)
pass
第八章
面向对象:继承、多态和封装
封装:把内容封装到某个地方,便于后面的使用
- 把内容封装到某个地方
- 从另外一个地方去调用呗封装内容
对于封装来说,其实就是使用初始化构造方法将内容封装到对象中,然后通过对象直接或者self来获取呗封装的内容
继承:和字面意思相同,即子继承父的内容【属性和行为】,反之不一定成立。就是将多个类的共有方法提取到父类中,子类仅需继承父类而不必一一去实现
析构方法
__del__()
:当一个对象被删除或者销毁时,python解释器也会默认调用这个方法,程序在结束的时候会自动调用这个函数。
class Animal:
def __init__(self,name):
self.name = name
print('这是构造初始化方法')
pass
def __del__(self):
print('这是析构方法')
pass
pass
dog = Animal('dog')
#结果为:
#这是构造初始化方法
#这是析构方法
在调用函数del
删除某个对象的时候,也会调用析构函数
当整个程序脚本执行完毕后会自动调用__del__
方法
当对象被手动销毁时也会自动调用此函数
析构函数一般用于资源回收,利用__del__
方法销毁对象回收内存等资源
单继承
class Animal:
def eat(self):
pass
def drink(self):
pass
pass
class Dog(Animal):
def wwj(self):
print('小狗汪汪叫')
pass
pass
class Cat(Animal):
def mmj(self):
print('小猫喵喵叫')
pass
pass
d1 = Dog()
d1.eat() #具备了父类的行为,是继承了父类的行为
在每个子类中实现自己独有的行为,可以减少代码的重复
class 子类(父类):
? 行为
? pass
多继承
同时可以继承多个父类
class 子类(父类1,父类2):
? 行为
? pass
class shenxian:
def fly(self):
print('神仙会飞')
pass
pass
class Monkey:
def chitao(self):
print('猴子喜欢吃桃')
pass
pass
class sunwukong(shenxian,Monkey):
pass
swk = sunwukong()
swk.chitao()
swk.fly()
当多个类中存在存在相同方法的时候,应该调用哪一个?
从左到右,一层一层,先找到谁就先执行谁
继承的传递
可以一级一级的传递,和多继承类似
重写父类方法
在子类中的方法可以将父类进行覆盖,由于父类中已经存在相同的方法,在此相当于方法的覆盖
调用父类方法
在重写父类的方法中,利用class在重新写一下父类发方法
还可以使用super().__init__()
#super是自动找到父类,进而调用方法,若继承了多个父类,会按照顺序逐个的去寻找,在调用找到的第一个。
多态
定义时的类型和运行时的类型不一样,此时就可以成为多态。
同一种行为,对于不同的子类,有着不同的行为表现
要想实现多态 必须有两个前提条件:
- 继承,多态必须发生在父类和子类之间
- 重写,子类需重写父类的方法
# 多态 案例演示
class Animal: #父类
def say_who(self):
print('我是一个动物')
pass
pass
class Duck(Animal): #子类 鸭子类
def say_who(self): #子类重写父类的方法
print('我是一只鸭子')
pass
pass
class Dog(Animal):
def say_who(self): #子类重写父类的方法
print('我是一只狗子')
pass
pass
class zhang:
def say_who(self): #子类重写父类的方法
print('我是zhang')
pass
pass
def commonInvoke(obj): #统一调用的方法
obj.say_who()
pass
# duck1 = Duck()
# duck1.say_who() #结果是 我是一只鸭子
# Dog1 = Dog()
# Dog1.say_who() #结果是 我是一只狗子
listObj = [Duck(),Dog(),zhang()]
for item in listObj:
commonInvoke(item) //体现了多态
pass
多态可以增加程序的灵活性,增加程序的扩展性
类方法和静态方法
一般使用的方法为实例方法,类对象所拥有的方法为类方法,需要使用装饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般是cls作为第一个参数,其余类似实例方法
class People:
country = 'China'
@classmethod #这是类方法
def get_Country(cls):
return cls.country #访问类属性
pass
@classmethod
def change_Country(cls,data):
cls.country = data
pass
pass
pass
print(People.get_Country()) #通过类对象直接去应用
p=People()
print('实例对象访问 %s'%p.get_Country()) #实例对象也可以访问类对象
People.change_Country('英国')
print('实例对象访问 %s'%p.get_Country()) #实例对象也可以访问类对象
静态方法,需要使用@staticmethod 来表示静态方法,静态方法不需要任何参数
为什么要使用静态方法
由于静态方法主要来存放逻辑性的代码,本身和类以及实例并没有交互,不会涉及类属性和实例属性的操作,故一般不需要任何参数
数据资源能够得到有效的充分利用
#返回当前的系统时间
import time
class TimeTest:
def __init__(self,hour,min,sec):
self.hour = hour
self.min = min
self.sec = sec
pass
@staticmethod
def showTime():
return time.strftime('%H:%M:%S',time.localtime())
pass
pass
print(TimeTest.showTime())
第九章
私有化属性(封装)
为了更好的保存属性安全,即不能随意修改,将属性定义为私有属性,添加一个可调用的方法去访问
私有属性,利用两个下划线开头。__属性
使用场景:
- 把特定的属性进行隐藏,不想让类的外部直接调用
- 保护该属性,不想让这个属性值随意改变
- 保护这个属性,不想让子类继承
#属性私有化
class Person:
def __init__(self):
self.__name = '李四' #加两个下划线 将此属性私有化 在外部不能使用,在类的内部可以使用
self.age = 30
pass
def __str__(self):
return '{}的年龄是{}'.format(self.__name,self.age) #私有化可以在内部使用
pass
pass
class Student(Person):
def printInfo(self):
print(self.__name) #在此访问父类中的私有属性,是不可以的
pass
xl = Person()
# print(xl.__name) # 会报错,私有化之后不能再外部直接访问
- 私有化的【实例】属性 不能在外部直接访问 可以在类的内部随意使用
- 子类是无法继承父类的私有化属性的 只能继承父类公共的属性和方法
- 类属性和实例属性一样,都是不能在外部直接访问
私有化方法
有些重要的方法,不允许外部调用,防止子类意外重写,把普通的方法设置成私有化方法
在前面加两个下划线__
Property属性
方法一针对上述私有化的情况,可以才用属性函数(property)的方法
#Property
class Person:
def __init__(self):
self.__age = 18
pass
def get_age(self):
return self.__age
def set_age(self,age):
if age < 0 :
print('年龄不能小于0')
else:
self.__age = age
pass
pass
# 定义一个类属性,实现通过直接访问属性的形式去访问私有的属性
age = property(get_age,set_age)
pass
p1 = Person()
# print( p1.get_age() )
print(p1.age)
方法二采用装饰器的方法实现
#Property
class Person:
def __init__(self):
self.__age = 18
pass
@property #用装饰器修饰,添加属性标志 提供一个getter方法
def age(self):
return self.__age
@age.setter #提供一个setter方法
def age(self,age):
if age < 0 :
print('年龄不能小于0')
else:
self.__age = age
pass
pass
pass
p1 = Person()
# print( p1.get_age() )
print(p1.age)
__new__
方法
- 创建并返回一个实例对象,如果
__new__
只调用了一次,就会得到一个对象。继承自object的新式类才有new这一魔法方法 - 注意事项
- 是对象实例化的时候所调用的第一个方法
- 至少必须要有一个参数是cls,代表要实例化的类,此参数在实例化时由python解释器自动提供
- 该魔法方法可以决定是否要使用该
__init__
方法,因为__new__
可以调用其他类的构造方法或者直接返回别的实例对象最为本类的实例,如果__new__
没有返回实例对象则__init__
不会被调用 - 不能调用自己的
__new__
方法
单例模式
确保某个类在该系统中只有一个实例存在,是一种常用的软件设计模式
class DataBaseClass(object):
def __new__(cls, *args, **kwargs):
#cls._instance = cls.__new__(cls) 不能使用自身的new方法
if not hasattr(cls,'_instance'): #如果不存在就开始创建
cls._instance = super().__new__(cls, *args, **kwargs)
return cls._instance
pass
错误与异常处理
有一些代码块
try: 可能出现错误的代码块
except:出错之后执行的代码块
else:没有出错的代码块
finally:不管有没有出错都执行的代码块
try:
print(b) #捕获逻辑代码 try里面有多个错误,但是只会捕获第一个错误
pass
except NameError as msg: #这是名称错误
#若捕获到错误,才会在这里执行
print(msg)
pass
except IndexError as msg:
#若捕获到错误,才会在这里执行
print(msg)
pass
except Exception as result: #都可以捕获的错误类型
print(result)
pass
print('初次接触异常处理')
print('HAHAHAHAHAHA')
#结果
#name 'b' is not defined
#初次接触异常处理
#HAHAHAHAHAHA
except 在捕获错误异常处理的时候 只要根据具体的错误类型来捕获的
该捕获机制是可以跨越多重调用的 不需要在每一个可能出错的地方去捕获
自定义异常
自定义异常,都要直接或间接继承Error或Exception
由开发者主动跑出自定义异常,在python中使用raise关键字
class Toollong(Exception):
def __init__(self,leng):
self.len = leng
pass
def __str__(self):
return '输入的数据长度是'+str(self.len)+'超出长度了'
pass
def name_Test():
name = input('请输入姓名。。。')
if len(name) >= 5:
raise Toollong( len(name))
else:
print(name)
pass
name_Test()
python动态添加属性和方法
__slots__
属性
限制动态属性的添加。只有在__slots__
变量中的属性才会被添加,其他的属性会添加失败,slots属性子类不会被继承,只有在当前类中才有效