Python基础语法学习笔记V1


python

python安装方法

http://www.python.org

python的使用

  1. python的交互式环境进入,win10中采用win+R快捷键进入运行窗口,输入python进入python。exit( )或者quit()退出交互式环境。

  2. 申明一个.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,因为变量ab在内存中的地址是相同的

在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属性子类不会被继承,只有在当前类中才有效