class1
'''
这节课的主要内容:
1.编码的规范
2.缩进的重要性
3.代码的注释操作
4.弱数据类型定义
'''
# 定义a变量,进行循环输出a的值,一直到a>10时,结束循环
# a = 0 # 这是对本行代码的说明
# while a < 10:
# print(a)
# a += 1
'''
变量的使用:
1. 定义变量,并取名。以便于后续通过变量名来使用该变量。
2. 对变量进行赋值操作,一般写法都是 变量名 = 值,意味着变量将具备有已赋好的值
3. 命名都是小写
变量的本质,其实就是
1. 在内存空间生成有数据
2. 数据同步会在内存空间中通过地址来进行管理。
3. 定义一个变量,并且赋值其实就是将地址指向了一个变量而已。
'''
b = 20
print(id(b))
b = 21
print(b)
# 定义name变量与age变量
name = 'lcx'
age = 11
# 定义循环,将内容进行循环输出
for i in range(0, 1):
print(i) # 循环体的输出操作,当行注释,用于解释当前行代码的含义
'''
1. 常量的命名是全大写
2. 常量的值一般都不会轻易更改
3. 常量和变量的定义区分,其实是人在区分,不是电脑。
'''
# URL = 'http://localhost:8080'
'''
变量的定义和使用:
变量的名称是可以随意改变的。
变量是通过赋值来进行数据的存储和引用
变量一定要赋值
变量的应用实际上就是应用的变量指向的内存地址的值。
变量在同一时间只能有一个值。多个变量可以同时指向一个内存的值
'''
value = 'hcc1'
print(value)
print(value + '123')
value = 'hcc123'
print(value)
# 可以一次性给多个变量赋值
hcc = k = emma = '厉害'
print(hcc)
print(k)
print(emma)
# 可以一次性给多个变量赋不同的值:根据变量的定义顺序依次进行赋值
hcc, k, emma = '厉害', '不菜', '身体健康'
print(hcc)
print(k)
print(emma)
'''
基本的数据类型
Python中常规的数据类型主要分为以下几种:
1. Number(数字)
2. String(字符串)
3. List(列表)
4. tuple(元组)
5. set(集合)
6. dictionary(字典)
7. bool(布尔)
8. None(无)
'''
# Number数据类型:表示数字类型,所有的数字都属于Number类型,包括有整数型(int)和小数型(float)的内容
age = 18
money = 12.83
math = -1
d = True
e = 1.1
print(type(age)) # type()固定写法,用于获得变量的数据类型
print(type(money))
print(type(math))
print(type(d))
print(type(e))
# String:表示字符串类型:在程序世界里,所有的文字都属于字符,一连串的字符叫做字符串。但是,在python语言中,只要是字符,就都属于字符串
name = '这是单引号字符串' # 定义一个字符串,可以通过''或者""实现
addr = "这是双引号字符串"
print(type(name))
print(type(addr))
demo = '听闻鲁迅先生一句话:"这世上本无路,走的人多了,就有了路"' # 如果要生成的字符串本身有引号在,则用另外一种引号与其进行区分
# 因为demo是用单引号括起来的,所以内部的引号用双引号,这样两者就不会冲突,双引号可以正常输出
print(type(demo))
print(demo)
path = r"D:\黑核\Linux基础" # 路径属于字符串,但是在路径前记得添加r,表示将特殊字符普通化,一般只在路径的字符串前方添加r,表示为原文输出,这样也可以实现转义
print(path)
temp = '听闻黄先生一句话:\'都**兄弟!别怕\'' # 字符串的内容包含有单引号,但是单引号本身是特殊字符,所以用\将字符串中的单引号转义为普通字符 \表示转义字符
print(temp)
# 对于路径的处理可以通过转义字符来转义\
path = "C:\\desktop\\学习视频.avi"
print(path)
# List列表类型:通过[]括起来的内容,是一个序列。可以管理多个值,每一个值都是一个独立元素,不同元素之间不会有任何关联,可以是任意值
li = [1, 2, 3, 4, 5, 6, 7, 8, 9]
li1 = ['1', 2, 3, 4, 5, 6, 7, 8, 9]
print(li1)
print(li[0]) # 如果要获取list中的特定的元素,需要通过下标来进行获取,下标是从0开始的。
# tuple元组类型:与list非常相似,都属于序列范畴。但是是基于()来进行管理的。
tu = ('hcc', 18)
print(type(tu))
print(tu[0])
# set类型:集合,特殊的序列,通过{}来实现,是一个不会有重复值的序列,并且会给你进行排序
wang = {'a', 32, '黄财财', '3', 32, '3', 'a'}
print(type(wang))
print(wang)
# dict类型:dictionary字典,Python特殊的序列类型,所有内容都是基于键值对的方式来实现管理的。key : value的形态,与set一样 也是通过{}管理
# 字典的写法格式是key:value,必须一一对应,每一组kv对都是通过,分割
di = {
'name': 'lcx',
'age': 16,
# 'age': 20 # 字典格式下,key是唯一的字符串。不能重复
}
print(di['name'])
print(di['age']) # 字典中所有的value都是通过key来进行获取的 K是name,value是lcx
print(di)
print(type(di))
k = 'key'
mss = {
'age': 16,
k: 333 # 等同于 'key':333
}
# 额外的基础数据类型,bool类型:真(True)和假(False)
# 成立的、正确的就是真,也就是True,与之相反的就是False,同时0代表假,其他代表真
status = True, False
a = True
b = False
print(type(a))
print(type(b))
# None,特殊的类型,表示没有,和""是两个概念
a = None # 表示啥都没有,null,内存地址都没有
b = "" # 表示为空,有内存地址,只是内存地址没有值
print(type(a))
print(id(b)) # id是看内存地址的
class2
'''
常见的逻辑运算符:
1. 基本的加减乘除:一定是针对同数据类型的不同数据进行的计算
2. 比较运算符
3. 赋值运算符: +=、-=、*=、/=
4. 逻辑运算符
and or not 表示 与 或 非 的逻辑
5. 成员运算符
数据类型的切换:
在编程世界里,每一种运算都是需要关联到数据类型的。为了让运算的过程中数据类型保持一致,会有一个叫做数据转型的操作
在强制转型的时候一定要考虑被转对象的内容是什么。一定要满足转型后的数据类型的值才可以正常转型。
面试题:
对list进行去重处理
所有的技术其实都是基础,所谓的高级只是把多个基础合到一起应用,就变成高级了
'''
# 加减乘除:+ - * /
# 基本的加法运算,只限于数字类型Number类型进行运算。
a = 1
b = 2
c = a + b
print(c)
# string类型也可以做加法运算。用于拼接字符串,字符串的拼接只限于str对str,不能够跨数据类型进行拼接 如String不能和int拼接
a = '李存鑫'
b = '123'
c = a + b
print(c) # 字符串只能拼接,即只能加法,不能减法
a = 'hcc' + '叫你来上课啦~'
print('这里是一个基本的字符串:' + a)
# 列表的加法运算:列表的合并,将多个不同的list变成一个完整的list
a = [1, 2]
b = ['a']
c = a + b
print(c)
print(a + b)
# 减法:只限于Number类型
a = 3
b = 1
c = a - b
print(c)
# 乘法
c = 3 * 3
print(c)
print('123' * 20) # 将'123'字符串重复输出20次,可以快速将需要重复的字符串进行重复输出,只需要定义到乘数即可。
print('-' * 100)
# 除法
c = 1 / 3
# c = 3 / 0 # 除数不能为0
print(c)
# ---------------------------------------------------------------------------------------------------------
# 比较运算符:==,将两者进行对比的运算符。对比两者是否相等。如果相等则返回True,否则为False
a = 1
b = 2
print(a == b) # 一个=号表示将右边赋值给到左边,两个=号表示两者进行对比,看是否相等
print('a' == 'a') # == 表示判断两者是否相等,将左右的值进行比较。相等返回True,否则返回False
print(123 == '123') # 非相同数据类型,所以一定是False
# 判断两者是否不相等 !=
a = 1
b = 2
print(a != b)
print(2 != 2) # !=判断两者是否不相等。如果不相等则返回True,否则返回False
# > >=表示大于和大于等于,< <=表示小于和小于等于,都与常规的数学概念一致。只能应用在Number类型之中。
# ---------------------------------------------------------------------------------------------------------
# 赋值运算符
a = 1 # 表示将1赋值给a,赋值是将右边的值赋给左边
print(a)
# 加法/减法/乘法/除法的赋值运算符,一般计数的时候用的比较多
a = 0
for i in range(0, 10): # 循环10次
print(a)
a += 1 # 相当于a = a + 1,也就是在a原有的值上+1,此逻辑同样可以在- * /中使用
# ---------------------------------------------------------------------------------------------------------
# 逻辑运算符:or and not这一类型被称作逻辑运算符
# and运算符:表示条件1 and 条件2 ,如果条件1为False,则直接返回False,如果条件1为True,再来看条件2,也为True,则返回True
print(1 == 2 and 2 == 2)
print(True and False)
# or运算符:表示条件1 or 条件2,只要两者中有一个为True,则返回True
print(1 == 2 or 2 == 2)
print(True or False)
# not运算符:表示not 条件1,表示不为条件1,如果成立返回True,否则返回False
print(not False)
# is:表示条件1 is 目标,表示条件1是否为目标,一般用于做类型判断或者非None校验
print(a is None)
print(type(1) is int)
# ---------------------------------------------------------------------------------------------------------
# 成员运算符:in和not in,两者规则相反
# in表示条件1是否在条件2之中。也就是包含关系,in的格式下,一定是左边被包含在右边。 一般用于在序列之中进行内容的判断
a = 'hcc'
b = 'c'
print(b in a)
print(b not in a)
print('a' in [1, 2, 'a'])
print('a' in 'aaaaa')
# not in与in相反。
# ---------------------------------------------------------------------------------------------------------
# 数据转型:将数据从原有的类型转变为另外的类型。
# 一种方法叫做强制转型,另一种叫做自定义转型。数据转型,一定要遵循基本的规则,也就是可以转的情况下才能够进行转型。不能随便转。
a = '123'
print(type(a)) # str类型
b = int(a) # 将a强制转型为int类型
print(type(b))
# ---------------------------------------------------------------------------------------------------------
print('-' * 100)
di = {
'name': 'hcc',
'age': 17
}
print(list(di)) # 只有Key,没有value
li = []
for key, value in di.items():
li.append(key)
li.append(value)
print(li)
# 面试题
# 对list进行去重处理
li = [1, 2, 5, 3, 2, 1, 6, 43, 5, 2, 10]
se = set(li)
print(se)
li1 = list(se)
print(li1)
li2 = []
for i in li:
li2.append(str(i))
print(','.join(li2))
'''
针对list和dict两种类型的常用操作。
'''
# list类型
li = ['b', 'e', 'a', 2]
print(li)
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
print(a)
# 通过下标获取指定的元素
print(a[0])
# 在list末尾增加一个元素
a.append('hcc')
print(a)
# 删除一个元素,del删除元素,remove删除
del a[3] # 基于下标进行删除
print(a)
a.remove('hcc') # 基于元素的值(remove函数删除元素是通过值,而不是下标)
print(a)
# 获取list长度
# len()函数用于获取序列的长度
print(len(a))
# 对list的内容进行排序:前提条件,元素都为同一数据类型才可以进行排序
li1 = [2, 3, 6, 1, 10, 8, 5]
li1.sort() # sort排序会修改原有的list顺序
print(li1)
li2 = [2, 4, 3, 8, 7, 13, 11]
print(li2)
print(sorted(li2)) # 临时顺序的变化sorted不会修改原有list的顺序
print(li2) # 又恢复原有的list顺序
# 合并list
print(a + li1)
# ---------------------------------------------------------------------------------------------------------
# 字典的数据类型操作
# 创建空字典
a = {}
b = dict()
set1 = set() # 这是创建空集合
# ---------------------------------
di = {
'name': 'hcc',
'age': 17
}
# 通过key来获取字典中的value值
print(di['name'])
# 删除一组kv对
del di['age']
print(di)
# 新增一个kv对在原有的字典中
di['sexual'] = '男'
print(di)
# 对已有的内容进行修改
di['sexual'] = 'male'
print(di)
# 字典的删除是通过key删除指定的kv对
del di['sexual']
print(di)
# 清空字典的内容
di.clear()
print(di)
# 字典中获取所有的key
print(di.keys())
# 字典中获取所有的value
print(di.values())
# 字典中获取所有的键值对
print(di.items())
# 获取字典的所有内容,一般而言都是通过循环的方法来获取的。
b = {}
for key, value in di.items():
b[key] = value
break
print(b)
# ---------------------------------
for key in di.keys():
# print(key)
print(di[key])
'''
String数据类型的常用操作。
'''
# 字符串的格式化输出:占位符的概念。在不改变原有的str内容格式基础上,将指定的内容添加到需要添加的位置。
name = '自动化'
print('Python{0} is the Best{1}!'.format(name, 'aaa'))
cla = 'Python'
name = '小熊'
a = f'今天我教你们的课程内容是{cla},请各位同学认真学习,尤其是{name}迟到了,记得课后好好补补,好好实操,以便于把内容掌握好。'
print(a)
# 多行字符串的输出,使用三引号,和注释的写法一样,但是需要赋值。这种写法不需要转义。因为所有的内容都是字符串。除了转义字符
content = '''
<html>
<header>
<body>' \\"
</html>
'''
print(content)
# 多行字符串输出:如果我们需要获取一长段文字,同时需要保留该段内容的格式。比如html,可以通过多行字符串的形态来输出,与多行注释一样的写法。
a = '''<html>
<head></head>
<body>
<a id="aging-total-page" role="pagedescription" aria-label="欢迎进入 百度一下,你就知道,盲人用户进入读屏幕模式请按快捷键Ctrl加Alt加R;阅读详细操作说明请按快捷键Ctrl加Alt加问号键。" tabindex="0" href="javascript:void(0)"></a>
</body>
</html>
'''
print(a)
# 字符串编码:修改编码格式,便于将获取的内容以正确的编码格式显示,从而不影响正常的数据使用(有时候会从其他文件进行内容的读取,读取后显示为乱码的格式)
str1 = 'HCC Python Class' # 普通字符串
print(str1)
str2 = str1.encode(encoding='GBK') # encode用于将原有的编码格式改为GBK
print(str2)
print(str2.decode(encoding='GBK')) # decode 基于gbk的编码格式解析内容
# 大小写的切换
a = 'abcDefg'
print(a)
# 全大写 Upper
print(a.upper())
# 全小写 lower
print(a.lower())
# 首字母大写
print(a.capitalize())
print(a.title())
# 去除字符串中存有的空格
a = ' zsada asd '
b = '000000000asd000000'
print(a)
print(b)
# 去除字符串中的空格,默认去除首尾的空格,如果是去除左边或者右边的空格,则考虑lstrip()或者rstrip()
print(a.strip())
# 去除首尾指定的字符
print(b.strip('0')) # strip函数的用途:去除首尾指定的字符,不输入参数则去除空格
# 字符串的内容替换
print(a.replace(' ', '')) # replace需要传入两个数据,第一个数据表示字符串中需要被替换的内容,第二个数据表示修改后的内容
print(a.replace('a', 'hcc', 1)) # replace有第三个参数,就是替换的总次数
# 字符串的分割:字符串内容进行处理的时候,需要进行字符串的分割,需要调用split()函数
a = 'hcc is cc'
print(a.split()) # 默认基于空格进行字符串的分割,会按照顺序保存为一个list,分割后的每一个值都是list中的一个元素
print(a.split('c')) # 输入一个参数,表示基于该参数值来对目标字符串进行分割
print(a.split('c', 1)) # 第二个参数,表示分割的次数
b = a.split()
b[2] = 'best'
print(b)
# 拼接字符串
print(' '.join(b)) # 将不同的字符串拼接成一个完整的字符串,每个字符串之间通过' '进行连接
# 指定切分的数据内容
b = 'hccxsaysxPythonxisxthexBest!'
print(b.split('x'))
c = b.split('x') # 拆解后的字符串
# 设置切分次数
print(b.split('x', 3))
print(c)
class3
'''
For循环语句结构:
for 循环条件:
for语句块
循环中的临时变量不用于其他的代码逻辑,只限于循环之中使用,避免外界的变量与循环的临时变量为同名
循环是必须要有闭环的。但是,我们可以通过关键字来决定是否主观地退出循环。
终止循环:
1. 循环次数达到最大。
2. 代码报错
3. 关键字进行结束
break:退出整个循环
continue:退出本轮循环
'''
# li = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 循环读取一个list中的所有元素
# for i in li: # i是循环条件下的临时变量,只用于本次循环之中
# print(i)
# 通过循环来对list进行赋值
# li = []
# 进行循环次数的限制
# for i in range(0, 5): # range()会生成指定长度的临时整数列表list range(0, 5) 0 1 2 3 4
# el = input('请输入添加的元素:')
# li.append(el)
# print(li)
# for循环嵌套
# 通过循环来对list进行赋值
# li = []
# 进行循环次数的限制
# for i in range(0, 5):
# li1 = []
# for j in range(0, 2): # for循环嵌套
# el = input('请输入添加的元素:')
# li1.append(el)
# li.append(li1)
# print(li)
# 读取字典的所有内容
# di = {
# 'name': 'hcc',
# 'age': 18,
# 'sexual': 'male'
# }
# 通过key来获取value
# for key in di.keys():
# print(di[key])
# 读取字典中的key和value
# for key, value in di.items():
# print(key)
# print(value)
# 终止循环:代码报错以及关键字的使用
for i in range(0, 100):
# 将接收到的值作为除数
a = int(input())
if a == 1:
break # 结束整个循环,进入到循环外面的世界。 该循环后续的循环逻辑不再执行。
elif a == 2:
continue # 本次循环结束,进入到新的一轮循环之中,continue后面的代码(如 print)全部不再执行。
print(1 / a)
'''
IF判断语句的代码块。
最基本的固定的判断模板:
if 条件:
if代码块
else:
else代码块
当条件满足if的时候,就会执行if代码块,如果不满足则进入到else代码块
elif用于增强if...else...语句,增加更多的判断条件
判断的写法是以整体来进行的,针对单个值一般是通过一个if判断的语句块来实现。不会进行多个if的编写。
'''
# if判断
name = input('请输入名称:') # 支持用户的输入关键字
# print(name)
# if name == 'hcc':
# print('欢迎你,黄财财。来到Python的世界')
# elif name == 'xzl':
# print('欢迎你,小助理,来到这个世界')
# else:
# print('对不起,权限不够')
# if name == 'hcc':
# print('欢迎你,黄财财。来到Python的世界')
# if name == 'xzl':
# print('小助理')
# if name == 'emma':
# print('emma')
# 嵌套if判断: 用于解决在实际编码中可能会存有的多重条件判断的处理。
# if name == 'hcc':
# status = int(input('请选择你需要的操作:1. 上课/2. 打架/3. 写代码'))
# if status == 1:
# print('上课好')
# elif status == 2:
# print('打架是犯法的')
# elif status == 3:
# print('Python使你成长')
# else:
# print('你输入的内容有误')
# else:
# print('对不起,权限不够')
# True和False来进行if判断的逻辑处理
if name:
print(name)
else:
print('请输入name值')
'''
while循环的语法结构:
while 条件:
while循环体
死循环,因为循环条件一直成立,则循环会永远持续下去,没有闭环。从而变成死循环。在使用while循环时,一定要注意避免死循环的出现。因为死循环一旦出现
代码逻辑就没有办法再继续运行了。
while循环一定要有退出循环的条件。否则会陷入死循环。
'''
# 基本while循环
# i = input()
# while int(i) < 10:
# print(i)
# i = input('请再次输入')
# print('循环结束')
# 调用 +=运算符生成循环的逻辑闭环
# a = 0
# while a < 10:
# print(a)
# a += 1
# 利用死循环机制: 实现我们需要的业务逻辑处理。一定要记住死循环中要有退出循环的条件。不然就真的死循环了。
while True:
command = input('欢迎进入人机交互的世界,请输入你的指令:1. 2. 3. 4. 如需退出请输入exit')
if command == '1':
print('1功能升级中~')
elif command == '2':
print('2功能升级中~')
elif command == '3':
print('3功能升级中~')
elif command == '4':
print('4功能升级中~')
elif command == 'exit':
break # 结束整个循环。
else:
print('输出错误')
class4
'''
函数的定义标准模板:
def 函数名(参数1,参数2,参数3.....):
函数代码块:如果函数没有逻辑代码,就用pass代替
def simple():
pass
pass关键字:如果内容不需要有任何的定义,直接写一个pass表示无内容。
调用函数,则直接通过函数名称()的形式来调用。如果函数中存有参数需要传递,则调用时函数名(参数1,参数2...)
如果函数需要传递参数,则参数的数量与实际传入的参数数量要保持一致。
参数传递:
形参与实参: 形参表示函数在定义的时候所定下的参数, 实参表示调用函数的时候实际传递的参数
在定义形参的时候可以给形参传递默认值,如果不给b参数传递新的实参,则在函数调用时会默认调用b的默认值 (如果给b参数传递新的实参,则在函数调用时会调用b的新参数)
def simple_sum(a, b=1):
c = a + b
print(c)
simple_sum(3) # 4
默认值的设定必须是在最后的参数中
'''
# 函数定义
def simple():
print('这是simple函数')
# 包含参数传递的函数
def simple_sum(a, b=1):
if b == 1:
print('这是通过默认值的逻辑处理')
else:
c = a + b
print(c)
# 函数的调用
simple() # 调用无参数的函数
simple_sum(3, 3) # 调用有参数的函数
'''
函数中参数传递的原理机制讲解:
python中,传递函数的参数其实就两个 *args 和 **kwargs
所有的函数在进行参数传递的时候,都会把参数变更为*args和**kwargs
*args表示元组的传递,可以接收无限制长度的参数
**kwargs表示字典的参数传递,可以接收指定key的字典格式的数据内容
*args表示不定值不定长传参
**kwargs表示定值不定长传参
*和**是什么时候需要解包什么时候用。
定值和不定值:
定值:(name='hcc') 指定了形参的名称
不定值:('hcc') 不指定形参的名称
'''
# *args参数的调用:其实就是参数的变化,*表示解包的意思。 包数据(1,2,3),通过*解包变成1,2,3
def demo(*args):
print(args)
demo(1)
def demo_normal(a, b):
print(a, b)
# 通过元组传递参数,必须要确保元组的元素数量与函数的参数数量保持一致
args = (1, 2)
demo_normal(*args)
# 解包的示例
def demo_1(args):
print(args) # 先是元组
print(*args) # 再是解开的 所以在哪里调用 在哪里加*解析(如果是元组加* 如果是字典加**)
demo_1((1, 2, 3, 4, 5, 6, 7, 89, 10))
# demo(1, 2, 3, 4, 5, 6, 76, 7, 8, 5, 454.6, .45, 646, 46, 46, 4, 64, 645, 64, 23, 12, 31, 2, 2321, 3)
# ---------------------------------------------------------------------------------------------------------------------
# **kwargs参数的调用:其实就是把参数解析为字典的形态进行传递。形参为key,实参为value,**表示字典的解包
def demo_dict(**kwargs):
print(kwargs)
demo('lcx')
# 字典的值:{'a' : 1,'b' : 2 }会解析为a=1,b=2
# def demo_dict(age, name):
# print(age, name)
# 通过字典传参:指定了参数名称和参数值来传递,则会以字典的格式来解析。
demo_dict(a=1, name='xxx')
di = {
'name': 'hcc',
'age': '18',
}
demo_dict(**di) # 实际上传值:demo_dict(name='hcc',age='18')
demo_dict(name='hcc', age='18')
'''
return:函数在实际调用的时候会根据代码逻辑需求会有返回值的产生。如果有则需要通过return关键字来定义
函数默认不会返回任何的内容,如果直接调用则返回None,加了return就会有返回值的调用
返回值,如果点菜的时候,有return,则会将菜返回到我们的桌上,如果没有返回值,则菜做好在后厨,不会到桌上来。
return的定义一定是要返回有明确内容,比如说数据类型,比如说对象。
return一定是写在函数的末尾。因为return执行后,整个函数就终结了,即时函数中还有代码没有运行,也会结束。
'''
# return关键字:将c返回回来,由此生成了一个变量。
def return_demo(a, b):
c = a + b
return c
# def return_none(a, b):
# c = a + b
# 无意义的return代码逻辑。
# def return_demo1():
# return print('hcc是这个无意义的函数')
# return的逻辑处理
# def return_demo2(a, b):
# if type(a) is int:
# return a + b
# else:
# return '你的输入有问题'
# print(type(return_demo(1, 2)))
# d = return_demo(1, 2) + 3 # 代码实际上 d = 3 + 3
# print(d)
# print(return_none(1, 2))
# c = return_demo2(1, 2)
# print(c)
'''
global的定义与使用:
作用域: 函数中的内容都是独立存在的,有效范围只在函数之中。外界的内容传入到函数中,也只会在函数内发生
改变,这个改变不会影响到外部。
global可以将函数外部的变量通过函数来进行值的修改。
'''
# 函数调用次数的计数
a = 0
# global
def global_demo():
global a # global 修改了指定变量作用域,可以将函数外的变量通过函数进行修改。让函数外的变量值发生变化
print('函数被调用')
a += 1
print(a)
for i in range(10):
global_demo()
print(a)
'''
递归函数与匿名函数的讲解:
匿名函数:不需要通过def来定义的一个一句话函数。
在python标准语法下,def定义函数,除此之外,有特定时候会需要有临时的函数定义。这种函数就是一个基本的表达式
不需要有复杂的逻辑代码块,而且是一次性使用的。需要使用函数,但是又不想专门定义函数的时候使用,懒人函数
通过lambda定义匿名函数
lambda 参数1,参数2...: 函数体
递归函数:递归函数就是循环,只是说循环调用自己。在逻辑概念上是一个比较绕的东西,一个不小心就容易陷入死循环
定义递归函数也要考虑函数需要有正常结束的条件
'''
# 匿名函数
# x = lambda a: a + 10 # 定义了一个匿名函数,要求传入参数a,执行a+10的计算。将函数赋值到x变量,相当于x就是一个函数
# print(x(10))
# # 多参数匿名函数
# y = lambda a, b: a + b # 定义一个函数,要求传入参数a和b
# 递归函数的实际应用
# 非递归案例
def multiplication(n):
num = n
for i in range(1, n):
num = num * i
return num
# 10次循环:1. 10*1=10,2.10*2=20,3.20*3=60......
print(multiplication(10))
# 递归调用:就是调用函数自己本身,但是一定要有出口,不能陷入死循环
def multiplication_plus(n):
if n == 1:
return 1
else:
num = n * multiplication_plus(n - 1)
print(num)
return num
'''
2
6
24
120
720
5040
40320
362880
3628800
3628800
'''
print(multiplication_plus(10))
# 例如解析字典格式的内容{key,value},当然value也可能会是一个字典,所以字典的格式很可能里面嵌套有多个不同的字典
class5
'''
类的定义: 类是定义的所有对象的共用方法和属性,所以一旦类的内容发生了变化,则实例化对象会相应地进行改变
class 类名:
类属性通过变量的赋值来进行定义
类属性是公共的,是不可以被实例化对象所修改的内容
类方法就是在类中定义函数,也就是类具备有的一些功能
类方法:在类中定义的常规函数
静态方法:不需要实例化,直接通过类名即可调用的方法
实例方法:通过实例化对象调用的方法
在定义类的时候一定是考虑此类的共同性。确保规范化
self参数:类自己。在定义普通类方法的时候,第一个参数一定是self,python中默认的表达,表示的是当前的类对象,也就是实例化参数,在实例化以
后就会生成self对象,self的有效适用范围只在类之中,出了类,self就不再是类他自己了。
构造函数:就是在实例化的时候需要做的事情,构造函数名字有且仅有__init__()
所有类都具备有构造函数,在不被定义的时候默认构造函数内容是pass,也可以定义构造函数来进行内容的修改。
构造方法主要适用于在实例化类的时候对于类之中的一些属性进行初始化定义。这样的 写法是更加规范化的。但是同时,构造方法也可以写入逻辑
'''
# 鱼的类
class Fish:
# 类中定义的变量叫做类属性,所有的类属性,在类中进行调用时,都是通过self.属性名的方式来实现的。
attribute_01 = '鱼鳍'
attribute_02 = '眼睛'
attribute_03 = '鳞片'
# 构造方法:在实例化时,对类的内容进行定义
def __init__(self, name):
# self.name意味着定义了一个类属性。
self.name = name
if name == 'hcc':
self.name = name
else:
self.name = 'MS'
# 类方法:在类方法中调用其他的类方法,也是通过self.方法名来实现。与类属性一样的。
def swimming(self):
print(self.name + '在水中游泳')
def breath_in_water(self):
print(self.name + '在水中呼吸')
def eat_in_water(self):
self.breath_in_water()
print(self.name + '在水中吃饭')
# 这是静态方法:类中的静态方法不需要self参数,也就意味着可以在不被实例化的情况下进行调用,也可以被实例化对象调用
@staticmethod # @符号表示装饰器,类似于java中注解的概念。
def function_demo():
print('这是静态方法')
'''
类的调用:实例化对象
类中的属性和方法在被调用的时候,其实调用的是实例化对象的属性和方法,而不是类本身,所以在进行实例化对象的内容修改时,改的是实例化对象,而不是类本身。
'''
# 类的实例化:类名()表示实例化。
# fish = Fish()
# # 通过实例化对象进行类方法的调用,实际上就是调用实例方法
# fish.swimming()
# fish.breath_in_water()
# # 实例化属性调用
# print(fish.attribute_01)
# fish.attribute_01 = 'fish的鱼鳍'
# print(fish.attribute_01)
# print(Fish.attribute_01)
#
# fish01 = Fish()
# fish02 = Fish()
# fish01 = Fish()
# # 修改类的属性:类名.属性名=修改后的值
# Fish.attribute_01 = '修改后的鱼鳍'
#
# print(Fish.attribute_01)
# # 实例化对象中对应的属性值会相应地进行变动。
# fish = Fish()
# print(fish.attribute_01)
# print(fish01.attribute_01)
# fish.eat_in_water()
# Fish().attribute_01 = '实例化的鱼鳍'
# print(Fish.attribute_01)
# 不同类方法的调用
fish = Fish('草鱼')
# 实例方法,通过实例化对象进行调用
fish.eat_in_water()
fish.swimming()
# 静态方法:不需要实例化,直接通过类名即可调用
# Fish.function_demo()
# 类方法:通过类名调用会提示缺少self参数,从而报错
# Fish.breath_in_water()
# fish.function_demo()
每个小模块,分类看 调试(类方法的调用 构造方法的调用),class1 class2…
'''
类的定义: 类是定义的所有对象的共用方法和属性,所以一旦类的内容发生了变化,则实例化对象会相应地进行改变
class 类名:
类属性通过变量的赋值来进行定义
类属性是公共的,是不可以被实例化对象所修改的内容
类方法 就是在类中定义函数,也就是类具备有的一些功能
类方法:在类中定义的常规函数叫类方法(不在类中定义的方法叫函数)
静态方法:不需要实例化,直接通过类名即可调用的方法
实例方法:通过实例化对象调用的方法
在定义类的时候一定是考虑此类的共同性。确保规范化
self参数:是类自己。在定义普通类方法的时候,第一个参数一定是self, python中默认的表达,表示的是当前的类对象,也就是实例化参数,在实例化以
后就会生成self对象,self的有效适用范围只在类之中,出了类,self就不再是类他自己了。
构造函数: 就是在实例化的时候需要做的事情,构造函数名字有且仅有__init__()
所有类都具备有构造函数,在不被定义的时候默认构造函数内容是pass,也可以定义构造函数来进行内容的修改。
构造方法主要适用于在实例化类的时候对于类之中的一些属性进行初始化定义。这样的 写法是更加规范化的。但是同时,构造方法也可以写入逻辑
'''
# 鱼的类
# class Fish:
# pass # 定义了一个类,这个类中没有任何的内容,就写一个pass(函数也是)
# -------------------------------------------------------------------------
# 鱼的类
class Fish:
# 类中定义的变量叫做类属性, 所有的类属性,在类中进行调用时,都是通过 self.属性名 的方式来实现的。
attribute_01 = '鱼鳍' # 类属性通过变量的赋值来进行定义
attribute_02 = '眼睛'
attribute_03 = '鳞片'
# 类方法: 就是在类中定义函数,也就是类具备有的一些功能 在类方法中调用其他的类方法,也是通过self.方法名来实现。与类属性一样的。
# def swimming(self):
# print('鱼在水中游泳')
# def breath_in_water(self):
# print('鱼在水中呼吸')
# def eat_in_water(self):
# print('鱼在水中吃饭')
# 这是静态方法: 类中的静态方法不需要self参数,也就意味着可以在不被实例化的情况下进行调用,也可以被实例化对象调用
@staticmethod # @符号表示装饰器,类似于java中注解的概念
def function_demo():
print('这是静态方法')
# 构造方法:在实例化时,对类的内容进行定义
def __init__(self, name):
# self.name意味着定义了一个类属性。
self.name = name
# 构造函数的类方法
def swimming(self):
print(self.name + '在水中游泳')
def breath_in_water(self):
print(self.name + '在水中呼吸')
def eat_in_water(self):
self.breath_in_water()
print(self.name + '在水中吃饭')
'''
类的调用:实例化对象
类中的属性和方法在被调用的时候,其实调用的是实例化对象的属性和方法,而不是类本身,所以在进行实例化对象的内容修改时,改的是实例化对象,而不是类本身。(两片内存空间,把类本身复制出来了一份内存空间)
'''
# 类的实例化: 类名() 即类名+括号 表示实例化
# fish = Fish()
# 通过实例化对象 进行类方法的调用,实际上就是调用实例方法
# fish.swimming()
# fish.breath_in_water()
# 实例化属性调用
# print(fish.attribute_01)
# fish.attribute_01 = 'fish的鱼鳍' # 在进行实例化对象的内容修改时,改的是实例化对象,而不是类本身(因为这个类可以被多个对象实例化) 类属性是公共的,是不可以被实例化对象所修改的内容
# print(fish.attribute_01) # 校验实例化对象的属性
# print(Fish.attribute_01) # 校验类本身的属性
# 这个类可以被多个对象实例化的举例: 然后通过多个不同的实例化对象来调用它
# fish01 = Fish()
# fish02 = Fish()
# ------------------------------------------------------------------------
# 如果想要修改类本身的值,即 修改类的属性: 类名.属性名=修改后的值 通过类名来调用
# Fish.attribute_01 = '修改后的鱼鳍'
# print(Fish.attribute_01) # 校验类本身修改后的属性
# 然后 实例化一个对象,校验实例化对象中对应的属性值也会相应地进行变动。
# fish = Fish()
# print(fish.attribute_01)
# ------------------------------------------------------------------------
# fish01 = Fish() # 校验在修改类本身的属性之前 先实例化一个对象,看修改类本身的属性之后,实例化对象调用类本身的属性,值会不会变动,结果是:实例化对象中对应的属性值也相应地变动了,变为修改后的值的了
# Fish.attribute_01 = '修改后的鱼鳍'
# print(Fish.attribute_01) # 校验类本身修改后的属性
# print(fish01.attribute_01) # 类是定义的所有对象的共用方法和属性,所以一旦类的内容发生了变化,则实例化对象会相应地进行改变
# fish.eat_in_water() # 类定义好之后,可以在类中再定义其他的类方法,如在上面类方法追加定义了‘鱼在水中吃饭’ ,所以fish. 就能点到该eat_in_water()类方法
# ------------------------------------------------------------------------
# 类名() 即类名+括号 表示实例化
# Fish().attribute_01 = '实例化的鱼鳍' # Fish后不加括号,就修改的是类本身的属性了, 类名后加了括号就表示 给这个类进行实例化对象的生成
# print(Fish.attribute_01) # 这是实例化之后的值 还是类本身的属性 鱼鳍 , 不是实例化修改的属性 实例化的鱼鳍
# ------------------------------------------------------------------------
# 以下是 不同 类方法的调用
# fish = Fish()
# 实例方法: 通过实例化对象进行调用
# fish.eat_in_water()
# fish.swimming()
# 静态方法: 不需要实例化,直接通过类名即可调用
# Fish.function_demo()
# 类方法: 通过类名调用会提示缺少self参数,从而报错
# # Fish.breath_in_water()
# fish.function_demo()
# ------------------------------------------------------------------------
# 构造方法的实例化 需要写name
fish = Fish('草鱼')
# 实例方法: 通过实例化对象进行调用
fish.eat_in_water()
fish.swimming()
'''
继承、封装、多态的定义
继承,是子类继承父类。
通过在class 类名(父类名): 来实现继承
继承之后,子类会具备有父类的所有特征,包括属性、方法、构造函数都会被继承。 可以将所有相近的类别进行继承的定义,提升代码的维护和逻辑性。
通过在父类中定义所有子类的共有属性与方法,从而让子类在继承时,可以快速具备基本的内容。降低代码的冗余,提升维护性。
多继承:一个子类继承一个父类是普通继承,一个子类继承多个父类则是多继承。多继承下,子类会包含有所有的父类的内容
多态,一个事务具备有多种不同的形态。相同父类下,不同子类调用同样的方法实现不同的结果。
方法重写:将父类中的方法在子类中重新定义。由此,不同子类中的同一个方法就会有不同的效果
方法重载:将同一个方法基于参数的不同,定义不同的逻辑。但是python语法不支持重载。
封装:可以实现到给你看你能看的,不想给你的一个都不给。
在做类的设计的时候,会很好地保证类内部的数据结构,让类可以更好地进行管理。
有些时候一部分的方法和属性,只是为了在类当中进行使用,不希望暴露在外。就会关联到私有属性和私有方法的定义。
私有属性:通过__属性名进行私有属性的定义,私有属性无法被实例化对象调用,也无法被子类所继承
私有方法:通过__方法名进行私有方法的定义,与私有属性一致。
'''
# 动物类父类
class Animal:
attribute_01 = '有毛'
attribute_02 = '尖牙'
attribute_03 = '舌头'
# 构造方法
def __init__(self, name='Animal'):
self.name = name
# 类方法
def scream(self):
print('尖叫,歇斯底里地叫')
def eat(self):
print('吃,狂吃')
# 宠物类父类
class Pet:
attribute_01 = '可爱'
attribute_action = '撒娇'
# 私有属性无法被子类所继承,只限于当前类独有
__age = 18
# 构造方法
def __init__(self):
self.name = '宠物系'
def action(self):
print('卖萌')
# 狼:是完全与animal类保持一致的。所以可以理解为,狼是animal类别的具象化
class Wolf(Animal):
# 多态的实现:方法重写
def eat(self):
print('围剿捕猎,利用战术实现进食')
# 方法重载:同一个方法,根据参数的不同,执行不同的效果
# def eat(self, a):
# pass
#
# def eat(self, a, b):
# pass
#
# def eat(self, a, b, c):
# pass
# 狗
class Dog(Animal):
# 多态的实现
def eat(self):
print('喂狗粮,喂零食,喂我们想喂的各种吃的')
# 猫:继承多个父类,不同父类之间用,隔开,如果多个父类具备有同样方法名的方法,则调用时,基于从近到远的原则进行调用
class Cat(Animal, Pet):
# 私有属性:只限于类内部使用,无法被实例化对象所调用
__type = '猫科动物'
# 公有属性
attribute_04 = '可爱'
# 公有方法
def demo(self):
print(self.__type)
# 私有方法
def __ccc(self):
print('这是私有方法ccc')
cat = Cat('hcc')
# print(Cat.__type)
# print(cat.name)
# print(cat.attribute_action)
print(cat.demo())
# print(cat.__type)
# wolf = Wolf('wolf')
# wolf.eat()
# dog = Dog('dog')
# dog.eat()
'''
Person类:定义了作为一个人类对象,应该要具备的基本能力
'''
class Person:
# 构造函数
def __init__(self, name, age, sexual):
self.name = name
self.age = age
self.sexual = sexual
# 类方法
def work(self):
print(self.name + '在工作')
def eat(self):
print(self.name + '在吃饭')
def info(self):
print("个人信息如下:")
print(self.name)
print(self.age)
print(self.sexual)
'''
对类进行调用的demo示例:
因为一个工程会有非常多的类和py文件的存在。针对不同的内容,用不同的文件进行管理,这样更加方便我们的使用。
遇到的问题就是会有一个py文件需要调用另外一个py文件中间的内容。
例如现在,在当前文件需要调用person.py文件中的内容。这就是python中的导包操作。而person.py文件就是所谓的模块
导入操作通过from ... import ...来实现。
导入模块可以导入自定义的py文件以及class对象和函数,也可以导入python的官方库
也可以导入第三方库,但是需要提前安装,在cmd中通过pip install 进行安装,安装是直接输入名字,名字一定要对,如果不知道是什么名字就百度搜一下
'''
# 导入模块操作
# from person import Person
# 导入person.py文件的所有内容
import person
# 官方自带库:东西很多。不一一介绍,有用到的时候会再教大家。
import os
import time
# 导入其他文件夹下的模块:自定义模块的导入只限于在当前工程中其他路径下的文件,其他工程下的文件无法导入
from class04.function_demo import simple
# 导入第三方库的内容
from selenium import webdriver
pe = person.Person('hcc', '18', 'male')
pe.info()
class6
'''
报错处理:
try...except就是对错误和异常的处理,通过try...except语法进行错误的处理后,程序将不会再终止运行
异常的处理,在调用try...except语法块之后就算是处理了。 不管是否真的成功解决问题。代码都不会再此处报错。
try:
可能出现问题的代码块
except Exception: # exception定义就是用来获取所出现的异常具体信息
如果报错了则进入到except代码块
else:
如果报错,则进入except,如果不报错则进入else中
finally:
不管前面的代码是什么情况,不管是否报错,反正最终都是会执行finally
except可以支持有多个,针对不同的异常进行不同的处理。这是合理的操作行为。但是,需要知道在实际处理的
时候,可能会忽略其他的异常,为了保障所有的异常都能够被捕获,可以通过用Exception类进行统一处理。
一般,在一个try的完整语法结构中,只会有一个finally。用于对于文件进行保存和关闭,资源的最终释放
raise关键字主要的目的是抛出用户自定义异常,解决因为业务原因而导致的自定义异常情况。
1. 直接定义raise虽然在pycharm中会出现有红线提示报错,但其实可以正常运行。
2. 可以手动抛出用户自定义异常。一般程序都是触发型报错,想要程序报错一定要触发报错的机制才可以。
所有的异常是基于BaseException作为父类来实现的。包括Exception类在内。所以如果定义一个自定义异常类,是
继承于BaseException类的话,则与Exception是同级的不同子类。
通过traceback更直观地将异常信息显示在控制台中,通过调用官方自带的traceback库来实现。
只需要在异常输出的地方调用traceback.print_exc()
'''
import traceback
# 定义一个自定义异常类,选择继承于Exception类即可。
class HccException(Exception):
pass
class demo:
def func_demo(self):
# 程序设计需求:需要通过用户传入小于10的数字,来执行除数为10以内的任意数值的除法计算
while True:
try: # try之中,将可能出现问题的代码进行编写
i = int(input())
if i >= 10:
raise HccException # raise的作用就是抛出一个异常。不再考虑触发机制,而是代码只要运行到raise就抛出异常
if i == 100:
break
c = 20 / i
except ZeroDivisionError as z: # except就是将对出现的问题进行解决的措施进行编写。
traceback.print_exc() # 通过traceback可以更加清晰显示出异常的详细情况
print('你输入的数据不能为0,请重新输入,谢谢')
print(z)
except ValueError as v:
print(v)
print('请输入数字,谢谢')
except Exception as e:
print('请输入非0以外的正常数字,谢谢。')
print(e)
raise e # 在except中是用于处理异常的。同时也可以选择不处理,继续将异常抛出。抛出异常用raise
# else: # 写不写无所谓,因为else中的内容在个人看来只是为了确保代码的完整性。
# print(c)
# finally: # 整个try体系中,最终不管结果如何都一定会执行的代码。一般是用于收尾的工作,将不必要的内容全部释放
# print('这是finally语法块里的内容,不管逻辑如何,最终一定会执行的代码。主要用于最后的收尾工作。')
# 如果要抛出异常,则最终必须要有一个接盘侠来处理这个异常。
try:
demo().func_demo()
except Exception as e:
traceback.print_exc()
class7
class8
'''
反射机制的解析:
反射机制都是基于字符串的形态来实现的动态调用。
1. getattr()就是通过此函数来获取目标对象的属性、方法
包含有两个参数:
1. 目标:可以是实例化对象,也可以是类本身
2. 名称:通过字符串的形态来输入
如果名称输入错误,则会报错。提示类没有对应的属性或者方法。
如果要获取的是方法,则记得在getattr()末尾再添加一个()。
在实际使用过程中一定要注意到名称的参数值的正确性,以及添加try...except来确保代码正确运行。
2. setattr()就是通过此函数来对对象的属性进行新值的设置。也可以增加新的属性。
3. hasattr()可以判断目标对象中是否包含有某个属性。返回True或者False,同时也可以基于方法名称来判断方法是否存在
4. delattr()用于删除目标对象中指定的属性:delattr()只能对类本身进行属性的删除,无法对实例化对象进行属性删除
'''
# 反射的示例
class Demo:
attribute_01 = '这是属性01'
attribute_02 = '这是属性02'
def func_demo(self):
print('这是类方法func_demo')
def func_demo1(self):
print('这是类方法func_demo1')
# 程序主入口
if __name__ == '__main__':
demo = Demo()
# 获取目标对象的属性。
# print(getattr(Demo, 'attribute_01')) # Demo.attribute_01
# li = ['attribute_01', 'attribute_02', 'attribute_03']
# for i in li:
# print(getattr(Demo, i))
# Demo.attribute_01
# Demo.attribute_02
# Demo.attribute_03
# print(getattr(demo, 'func_demo')) # 只是通过方法名获取到目标对象是否有这个方法。
# getattr(demo, 'func_demo')() # 相当于demo.func_demo()
# if name == 'func_demo1':
# demo.func_demo1()
# elif name == 'func_demo':
# demo.func_demo()
# 等同于
# getattr(demo,name)()
# setattr()
# 对已有的属性进行新值的设置
# print(demo.attribute_01)
# setattr(demo, 'attribute_01', 'this is new attribute value') # 等同于demo.attribute_01='this is new attribute value'
# print(demo.attribute_01)
# # 对目标对象进行新的属性设置。
# setattr(demo, 'attribute_03', 'this is 03')
# print(demo.attribute_03)
# hasattr()判断属性是否在对象中存在
# print(hasattr(demo, 'attribute_00'))
# print(hasattr(demo, 'attribute_01'))
# print(hasattr(demo, 'func_demo'))
# delattr()用于删除指定属性,只能用于属性,不能用于方法
# delattr(demo, 'func_demo') # 删除方法是会报错的。
# print(demo.attribute_01)
# delattr(Demo, 'attribute_01') # 删除已存在的属性
# # print(demo.attribute_01)
# delattr(Demo, 'attribute_00') # 删除不存在的属性,也会报错
'''
Yield关键字:其实就是讲迭代器、生成器、可迭代对象
可迭代对象:但凡可以通过循环来进行取值的都叫做可迭代对象。
迭代器:同属于可迭代对象,但是一次只取一个值,一直到全部取完为止。前提条件是程序没有终止的情况下。
生成器:其实也是迭代器,也就意味着是可迭代对象,通过yield关键字来声明的函数被称为生成器
常规我们所熟悉的函数返回值都是基于return来实现的。通过return的调用,会终止函数的运行。在python中
还有另外一种返回值的关键字叫做yield,带有yield关键字的返回,则是一种迭代器,在通过yield返回数据的
同时,函数的运行会在后台挂起,不会终结。
yield只用于函数之中。yield生成器很大的作用在于初期获取测试用的大批量数据内容。因为生成器的特性,每一组
数据来执行不同的操作,而这时候只需要一个数据文件即可。
生成器和迭代器都属于同样的性质:
1. 取值都是一个个取
2. 取值都是从前往后走,不能够回头。
3. 一直到取值完毕为止
'''
# 迭代器
# li = [1, 2, 3, 4, 5, 6, 7] # 定义一个list可迭代对象
# print(type(li))
# # 将li转换为迭代器
# it = iter(li)
# print(type(it))
# # 对迭代器进行取值操作:通过next()函数来获取值,一次只取一个值
# print(next(it))
# print('这是在迭代器取值后的操作')
# print(next(it))
# print('这是在for循环之前的操作')
# for i in it:
# print(i)
# 基于 yield关键字定义生成器
def func_demo(num):
while True:
if num < 0:
break
else:
num -= 1
yield num
a = func_demo(10)
# print(a)
# 通过调用yield定义的函数,会返回一个生成器对象,通过next获取其中的值,一次一个,直到获取结束为止
# print(next(a))
#
# # 调用for循环获取yield生成器函数的值
for i in a:
print(i)
print(next(a)) # 当迭代器或者生成器的值被取完之后,再继续取就会报错。
# @装饰器名称 用于做功能的增强。在原有的基础上增加更多的功能,还有就是进行解释(说明)