python学习笔记

python学习笔记,可能存在错误,大佬多指点

  • print()打印输出

                多个参数输出用逗号隔开,end='' 不换行输出

# 输出文字
print('Python')
  • input() 键盘接收指令

# 键盘接收指令
tip = input('请输入文字')
  • 注释

# 单行注释
"""多行注释-多行文本"""
'''多行注释'''
  • 编码规范

  1.  尽量不要使用类似java中的结束符
  2. 每个import尽量只导入一个模块
  3. 文字太长可以使用 \ 来换行 推荐使用()来进行换行
  4. 语句换行 () 超出80字需换行 导入模块语句不可用,注释中的url过长不可用
  • 保留字与标识符

        保留字

                and,as,assert,break,class,,continue,def,del,elif,else,except,finally,for,from,False,global,

                if,import,in,is,lambda,nonlocal,not,None,or,pass,raise,return,try,True,while,with,yield

        标识符

                _标识符        保护变量

                __标识符        类的私有成员

                __标识符__        专用标识        __init__() 构造函数

  •  变量

        python中不需要声明变量类型

# 字符串类型
str = 'Pyhton String'

# 整型
age = 18

# 浮点型
htight = 1.70

        python中变量是动态类型,可以变化

nickname = '张三'
print(nickname) # 结果为张三
nickname = '李四'
print(nickname) # 结果为李四

        python中允许多个变量指向同一个值,内存中只存在同一个值

no = num = 2048
print(no, num)
# 查看变量内存地址
print(id(no))
print(id(num))

        常量,值不可变,python中常量没有关键字,命名为大写便是常量,但是赋值后还会被改变,所以不常用

# 常量
SFZ = 1122233

        查看变量类型-使用type函数

str = '字符串'
print(type(str))
  • 数据类型    

        数据类型:整数、浮点、字符串、布尔

        1. 数字类型

                整数、浮点、复数、十进制、八进制、二进制、十六进制

                整数类型不需要管位数,当超出固定位数后,python会自动转为更高精度的类型

        2. 字符串类型

                python中字符串是不可变序列

                常用转译字符

                        \         续行符

                        \n        换行符

                        \0        空

                        \t        制表符

                        \"        双引号

                        \'        单引号

                        \\        单反斜杠 转译反斜杠

                        \f        换页

                        \0dd        八进制数,dd代表字符,如\012 代表换行

                        \xhh        十六进制数,hh代表字符。如\x0a 代表换行

                r 原始字符串-原样输出,不进行转译,例如字符串中的\会被认定为普通字符

                """xxx""" 三引号字符串可以保持原有格式进行输出

         3. 布尔类型

                True False

                true false 不是布尔值

                bool值转换数值 True = 1 False = 0

                假值:False,None,0,0.0,虚数0,空序列(空字符串、空元组、空列表、空字典),对象的__bool__方法返回False,__len__方法返回0

                真值:除上述假值外其他返回值都为真值

  • 数据类型转换

        int() 整型

        float() 浮点型

        str() 字符串

        hex() 十六进制

        cot() 八进制

  • 运算符

        算数运算符、赋值运算符、比较运算符、逻辑运算符、位运算符

                1. 算数运算符

                        + 、- 、* 、/ 、%

                        除法 / 结果为浮点数

                        除法 // 结果为整数

                        ** 幂运算

                2. 赋值运算符

                        += 、 -= 、 *= 、 /= 、 %=

                3. 比较-关系运算符

                        == 、 != 、> 、< 、 >= 、 <=

                4. 逻辑运算符

                        and 逻辑与 一假则假

                        or 逻辑或 一真则真

                        not 逻辑非 真变假 假变真

                5. 位运算符

                        & 位与 有0即为0

                        | 位或 有1即为1

                        ~ 位取反 0变1 1变0

                        ^ 位异或 全是0或全是1 才是0

                        << 左移位 左边最高位丢弃,右边空位用0补充,等于乘以2的n次幂

                        >> 右移位 右边最高位丢弃,左边最高位如果是0,则填充0,如果是1,则填充1,等于除以2的n次幂

                6. 运算符优先级

                        优先级高的运算先执行,优先级低的运算后执行,同一优先级的操作按从左到右的顺序执行

                        从上到下依次从高到低

                        1. 单目运算符  ~  +  - 

                        2. 算数运算符  *  /  %  //

                                                + - 

                        3. 位移运算符  &

                                                ^

                                                |

                        4. 比较运算符  <  <=  >  >=  !=  ==

                        可以使用 () 改变优先级 

  • 索引-序列

        在java中为数组

        python中为列表、元组、字典、集合、字符串

        序列:一块用于存放多个值的连续空间,并按一定顺序排列,可以通过索引取值

        索引就是编号 0开始

           切片、序列相加、乘法  对字典不支持     

            所以可以是负数,从后往前,从-1开始

             1. 切片

                        语法:sname[start : end : step]

                                        start: 起始位置、

                                        end: 结束位置

                                        step: 步长

                        start可以省略,冒号必须保留,end也可以省略,省略后默认值为1

                        切片不包含结束索引

sname = ['乔丹', '拉塞尔', '贾巴尔', '李宁', '科比', '詹姆斯', '张伯伦', '邓肯', '伯德', '阿尼尔']

# 指定开始及结束位置 输出结果['拉塞尔', '贾巴尔', '李宁', '科比']
print(sname[1:5]) 

# 指定从0开始到第五个 步长为2 输出结果['乔丹', '贾巴尔', '科比']
print(sname[0:5:2])

# 输出结果为0-4 5个 输出结果['乔丹', '拉塞尔', '贾巴尔', '李宁', '科比']
print(sname[:5])

# 输出结果为整个列表
print(sname[:])

# 输出结果为从第二个至结束
print(sname[2:])

                2. 序列相加

                        使用+号,把两个相同类型的序列合并成为一个,如果有重复的不会被剔除

                        只能是相同类型相加。列表 + 列表 元组 + 元组 字符串 + 字符串

                

sname = ['乔丹', '拉塞尔', '贾巴尔', '李宁', '川建国']
cname = ['马斯克', '川建国', '贾巴尔', '李宁']

aname = sname + cname

print(aname)

                3. 乘法

                        python中支持 序列 * 乘数 = 重复n次的序列

                        并非把元素内容相乘

phone = ['HuaWei Meta 60', 'Vivo x32', 'iphone16']
print(phone * 3)

                4. 检查元素是否为序列成员

sname = ['乔丹', '拉塞尔', '贾巴尔', '李宁', '科比', '詹姆斯', '张伯伦', '邓肯', '伯德', '阿尼尔']
# 检查元素是否在列表中
print('乔丹' not in sname)

                5. 计算序列的长度、最大值、最小值

                        常用方法

                                len() 列表长度

                                max() 最大值

                                min() 最小值

                                list() 将序列转换成列表

                                str() 序列转换成字符串

                                sum() 计算序列和

                                sorted() 元素排序

                                reversed() 反转序列元素

                                enumerate() 序列组合为索引序列

num = [10, 58, 65, 35, 33]
print('列表的长度', len(num))
str = '我是个字符串'
print(len(str))
  •   列表

        列表是内置的可变序列

        1. 列表的创建和删除

                赋值运算符直接创建, 使用 []

# 数值类型列表
num = [15, 22, 35, 105]

# 字符类型列表
verse = ['春眠不觉晓', 'python不得了', '夜来爬数据', '牢饭吃多少']

# 
python = ['优雅', "简答", """明确"""]

# 多类型列表
untitle = ['pyhton', 28, '人生苦短', ['云计算', '视觉', '爬虫']]

                创建空列表

# 创建空列表
unlist = []

                创建数值列表

# 创建数值列表 从2生成到21 步长为2
num_list = list(range(2, 21, 2))

                字符串转换成列表

str = 'hello world'
str_list = list(str)
print(str_list)

                删除列表- del()

str = 'hello world'
str_list = list(str)
print(str_list)
# 删除列表
del(str_list)

        2. 访问列表元素

                通过索引或者切片访问

python = ['python', 'java', 28, ['爬虫', 18, '人工智能']]

# 使用print()
print(python)

# 通过索引
print(python[2])

# 通过切片
print(pyhton[:2])

        3. 遍历列表

                1.  使用for循环

                2. 使用for循环和enumerate()

                3. 使用for循环和range()

                enumerate()  序列组合为索引序列

verse = ['春眠不觉晓', 'python不得了', '夜来爬数据', '牢饭吃多少']

# 使用for循环

for item in verse:
    print(item)

# 使用for循环和enumerate()
for index, item in enumerate(verse):
    print(index + 1, item)

# 使用for循环和range()
for i in range(0, len(verse)):
    print(verse[i])

        4. 添加、修改、删除列表元素

                1. 添加元素

                        append() 添加新元素

                        insert(self, item) 指定位置插入元素 没有append执行效率高

                        extend() 一个列表的元素全部添加到另一个列表中

verse = ['春眠不觉晓', 'python不得了', '夜来爬数据', '牢饭吃多少']

# append 添加新元素
verse.append('哈哈')

# insert() 指定位置插入新元素
verse.insert(0, '第一个元素')

# extend() 一个列表中的元素全部添加到另一个列表中
old_list = ['乔丹', '贾巴尔', '奥拉朱旺', '巴克利', '姚明']
new_list = ['基德', '纳什', '希尔']
old_list.extend(new_list)
                2. 修改元素

                        list[index] = 值

verse = ['春眠不觉晓', 'python不得了', '夜来爬数据', '牢饭吃多少']

# 修改元素
verse[-1] = '一行白鹭上青天'
                3. 删除元素

                        del list[index]

                        remove()

verse = ['春眠不觉晓', 'python不得了', '夜来爬数据', '牢饭吃多少']

# del[index] 删除元素
del verse[-1]

# remove() TODO 如果没有该数据则会抛出异常
verse.remove('夜来爬数据')
        5. 对列表进行统计计算

                count() 获取指定元素痴线的次数

                        list.count(obj)

                index() 获取指定元素首次出现的下标

                        list.index(obj)

                sum() 统计数值列表的和

                        sum(list, start) start为可选参数,与list所有的值再次相加

nba = ['乔丹', '贾巴尔', '奥拉朱旺', '巴克利', '姚明', '乔丹']

# 获取指定元素出现的位置
num = nba.count('乔丹')


# 获取指定元素首次出现的下标
index =  nba.index('贾巴尔')

num_list = [15, 20, 30, 50, 105]

# 统计数值列表的和
num_sum = sum(num_list)

# list所有的值相加后加100
num_sum_add = sum(num_list, 100)
        6. 对列表进行排序

                1.  sort() 列表对象,排序后原列表中的元素顺序不变

                        list.sort(key=None, reverse=False)

                                key = str.lower 不区分大小写

                                reverse = False 升序  = True 降序

                sort() 对中文排序效果不好  -  具体请自行尝试

                2. sorted() 内置对象

                        sorted(list, key, reverse)

num_list = [15, 20, 35, 33, 55, 33]

# 升序 - 原列表顺序不变
num_list.sort()



name_list = ['cat', 'Tom', 'Angela', 'pet']

# 对英文进行排序  升序 不区分大小写
name_list(key=str.lower())

# lambda
name_list(key=lambda x: x.lower())


# sorted 排序

list_px = sorted(name_list, key=str.lower, reverse=True) # 降序
        7. 列表推导式

                列表推导式可以快速生成一个列表

import random

# 原始生成方式
list1 = []
for i in range(10):
    list1.append(random.randint(10, 100))

# 使用列表推导式
list2 = [random.randint(10, 100) for i in range(10)]

# 生成1-10中偶数平方的列表 后面循环完成后前面才进行计算
list3 = [i*i for i in range(2, 10, 2)] 

price = [1000, 500, 800, 888, 666]
# 生成满足条件的 添加判断
sales = [i for i in price if i > 800]
  • 元组

        元组 tuple (元素1, 元素2, ...)

        元组类似列表,可以放置各种类型的数据

        元素使不可变的

        1.  创建和删除元组

               可以通过赋值运算符创建元素

                注意创建单个个数值元组时要加逗号  a = (15,)

# 元组的创建
number = (1, 2, 3, 4, 5, 6, 7, 8, 9)

mx = ('林俊杰', '房东的猫', '薛之谦')

# 混合类型元组
untitle = (15, '毛不易', 'pyhton', ['爬虫', '运动控制'])


# 以下并非元组
verse = ('我要学python')

# 创建单元素元组后面要加逗号
onese = ('我要学视觉',)

# 创建空元组
untuple = ()

# 创建数值元组
tuple1 = tuple(range(2, 21, 2))

                删除元组使用del

tuple2 = tuple(range(2, 21, 2))

# 删除元组
del tuple2

        2. 访问元组元素

                1. print() 

                2. 索引

                3. 切片

                4. for遍历

untitle = (15, '人生苦短', 'python', ['java', 'web'], ('爬虫', '云计算'))

# print()
print(untitle)


# 索引
print(untitle[4])


# 切片 不包含结束索引
print(untitle[1:3])

# for循环遍历
for item in untitle:
    print(item)

        3. 修改元组元素

                不可以直接修改-会报错

                只能重新赋值

                元组可以和元组进行组合,通过加号连接,不可连接其他类型

coffee_name = ('蓝山', '卡布奇诺', '曼特宁', '摩卡', '麝香猫', '哥伦比亚')

# 错误演示  直接修改 
# coffee_name[4] = '拿铁'


# 重新赋值
coffee_name = ('蓝山', '卡布奇诺', '曼特宁', '摩卡', '拿铁', '哥伦比亚')


# 元组进行连接组合
new_coffee_name = ('麝香猫', '维也纳')
all_coffee_nane = coffee_name + new_coffee_name

# 错误演示 
# print('合并后' + all_coffee_name)

        4. 元组推导式

                快速生成元组

               生成器生成内容访问后立即销毁

import random

# 生成包含10个随机数的元组
ran_num = (random.randint(1, 100) for i in range(10))

# 销毁演示
for item in ran_num:
    print(item, end = ' ')


# 此处访问结果为 () 空元组 上方for使用后立即销毁 所以此处为空元组
print(tuple(ran_num))
  • 元组和列表的区别

        元组和列表的区别 

        1. 元组和列表都属于序列,都可以按照一定顺序存放元素,类型不受限制

        2. 列表元素可变,元组不可变,只能替换

        3. 列表支持切片操作,元组只能切片访问

        4. 列表访问速度慢,元祖访问速度快

        5. 列表不能作为字典的键,元组可以作为字典的键

  • 字符串

        字符串定义的方式

                1. 'xxx'

                2. "xxx"

                3. """xxx"""

                1. 2. 必须在同一行,3. 可以换行

        1.  拼接字符串

                使用 + 拼接

                

h = 'hello'
w = 'world'
print(h + w)

str1 = '微信步数:'
num = 17777
print(str1 + str(num))

        2. 计算字符串的长度

                1. 英文字母 数字 小数点 下划线 空格 占一个字节

                2. 中文汉字2~4个字节,UTF-8占3个字节,GBK编码中文占两个字节

                len() 计算字符串长度

                        len(string)  中英文都按一个计算

                encode() 设置编码格式  不填写默认utf-8

str = 'hello world'
# 获取字符串长度
print(len(str))

# 获取utf-8长度
print(len(str.encode()))

# 获取GBK长度
print(len(str.encode('GBK')))

        3. 截取字符串

                字符串也属于序列

                1. 通过索引获取-下标

                        如果索引超长会报错 - IndexError

                2. 使用切片方式进行截取

                          如果切片起始值大于数据长度则会返回空

        

str = '人生苦短,何必学python'

# 通过下标方式获取
print(str[1])

# 通过切片方式截取
print(str[1:3])

        4. 分割字符串

                split() 分割字符串

                        str.split(sep, maxsplit)

                                sep: 分隔符,空格、换行\n、制表符\t,都可以作为分隔符

                                maxsplit: 分隔次数

                        不指定任何参数则默认用空格分隔

                join() 合并字符串

                        str. join(iterable)

                                iterable: 可迭代对象,字符,可以是列表,可以是元组

str_user = '@林俊杰 @房东的猫 @薛之谦'

# 不指定任何参数-默认用空格分隔
print(str.split())

# 指定分隔次数
print(str.split('', 3))


# 合并字符串
list_user = ['薛之谦', '林俊杰', '川建国']
str = '@'.join(list_user)
str_a = '@' + str
print(str_a)

        5. 检索字符串

                in : 判断字符是否存在

                count() 检索出现次数

                        str.count(sub[,start[,end]])

                find() 检索字符在字符串中首次出现的位置

                        str.find(sun[,start[,end]])

                rfind() 从右往左查找

                index() 检索是否存在字符串

                        str.index(sub[,start[,end]])

                rindex() 从右往左查找

                startswith() 检索是否以此字符串开头

                        str.startswith(sub[,start[,end]])

                endswith() 检索是否以此字符串结尾

str_star = '@林俊杰 @房东的猫 @薛之谦 @毛不易'
# 检索出现次数
print(str_star.count('@', 5, 10))

# 检索首次出现位置 返回索引 没有找到返回-1
print(str_star.find('@'))

# 检索字符串是否存在
print('@' in str_star)

# rfind 从右往左查找
print(str_star.rfind('@'))

# 检索是否包含字符串 存在返回下标 不存在抛出异常
print(str_star.index('@'))

# rindex 从右往左查找
print(str_star.rindex('@'))

# startswith 检索是否以字符串开头
print(str_star.startswith('@'))

# endswith 检索是否已字符串结尾
print(str_star.endswith('@'))

        6. 字母的大小写转换

                lower() 转小写

                upper() 转大写

str = 'WWW.mddn.net'

# 转小写
print(str.lower())

# 转大写
print(str.upper())

        7. 去除空格和特殊字符

                特殊字符: \t \r \n

                strip() 去除字符串左右两端空格和特殊字符

                        str.strip([chars]) 参数不指定默认去除空格

                lstrip() 去除左侧空格和特殊字符

                rstrip() 去除右侧空格和特殊字符

str = ' https://www.mddn.net \t \n \r'

# 去除空格
print(str.strip())

str1 = '*https://www.mddn.net \t \n \r'

# 去除*
print(str1.strip('*'))

str2 = '*https://www.mddn.net \t \n \r*'

# 去除左侧*
print(str2.lstrip('*'))

# 去除右侧*
print(str2.rstrip('*'))

        8. 格式化字符串

                1. % 

                        '%[-][+][0][m][.n]格式化字符串'%exp

                                [-] 左对齐 正数前面没符号,负数前面加负号

                               [+] 右对齐 正数前面加正号,负数前面加负号

                               [0] 右对齐 正数前面没符号,负数前面加负号,用0填充空白。和[m]一起使用 

                                [m] 数值所占宽度 和[0] 一起使用 不够m所指定位数补0

                                [.n] 小数点后保留位数 n = xxx数字

                                以上为可选参数

                                必选参数:

                                s: 字符串

                                d: 十进制

                                f: 浮点数

                                exp: 要转换的项,多个需要使用元组

                                todo 两边百分号不可缺少

                2. format()

                        str.format([args])

                                {[index][:[[fill]align][sign][#][width][.precision][type]]}

                                [index] 可选参数 在参数对象中索引的位置,从0开始,省略按照值的先后顺序自动分配

                                [fill] 指定空白处填充字符

                                align 对齐方式,

                                        < 内容左对齐

                                        > 内容右对齐

                                        = 内容右对齐,符号放置最右侧,只对数字类型有效,如果值为向上尖括号,内容居中,需要和width一起使用

                                [sign] 指定有无符号数

                                        + 正数加正号,负数加符号

                                        - 正数不变,负数加负号

                                        值为空格 正数加空格,负数加负号

                                [#] 用于指定进制前缀

                                        0b 二进制

                                        00 八进制

                                        0x 十进制

                                [windth] 指定宽度

                                [.precision] 指定保留的小数位数

                                [type] 要格式化的字类型

                                        s 字符串

                                        d 十进制数

                                        f 浮点数

                                index 要么全部指定 要么全部不指定

import math

# %9d 表示9位10进制数 %s 表示字符串
temp = '编号:%9d \t公司名称:%s \t 官网:https://www.%s.com'

# 数据
item = (7, '百度', 'baidu')

# 替换数据
print(temp % item)


# format
temp2 = '编号:{0>9s} \t 公司名称:{:s} \t 官网:https://www.{:s}.com'
context = temp2.format('7', '百度', 'baidu')
print(context)

# 以货币形式展示
print('货币:¥{:,.2f}元'.format(1251+3950))

# 科学技术法
print('{0:.1f}用科学技术法表示:{0:E}'.format(12000.1))

# π取5位小数
print('π取五位小数:{:.5f}'.format(math.pi))


# 十六进制显示
print('{0:d}的十六进制是:{0:#x}'.format(100))

# 百分比显示
print('天才是由{:.0%}的灵感,加上{:.0%}的汗水'.format(0.01,0.99))
  • 正则表达式  

        1. 正则表达式基础

                一种用来匹配字符串的规则,包含行定位符,元字符,限定符,字符类,排除字符,选择字符,转译字符,分组

                行定位符 定位开始和结束的 ^ 表示开始 $ 表示结束

                元字符 表达特殊意义的专用字符

                        ^ 开始

                        $ 结束

                        . 匹配出换行符以外的任意字节

                        \w 匹配字母、数字、下划线或汉字

                        \W 匹配字母、数字、下划线或汉字以外的字符

                        \s 匹配任意空白字符

                        \b 匹配单词的开始或结束

                        \d 匹配数字

                限定符 限定数量

                        ? 匹配前面的字符零次或一次

                        + 匹配前面的字符一次或多次

                        * 匹配前面的字符零次或多次

                        {n} 匹配前面的字符n次

                        {n,} 匹配前面的字符最少n次

                        {n,m} 匹配前面的字符最少n次,最多m次

                字符类 定义一个字符集合,匹配当中的字符 []表示

                排除字符类 匹配不符合字符集中的字符 ^ 表示

                选择字符  或 | 表示

                转译字符 \ 表示

                分组 ()表示

        2. 匹配字符串

                正则表达式需要引入的模块 re

                1. match() 从字符串开始位置进行匹配,其实位置匹配成功返回m对象,否则返回None

                        re.match(pattern, string, [flags])

                                pattern 模式 - 正则表达式

                                string 要匹配的字符串

                                [flags] 标志位

                                        re.i  不区分字母大小写

                                        re.A  让\w不匹配汉字

               2. search() 从整个字符串搜索第一个匹配的值

                        re.search(pattern, string, [flags])

                3. findall() 搜索所有符合条件的字符串,返回列表

                        re.findall(pattern, string, [flags])

import re

pattern = r'md_\w'
str = 'MD_SHOP md_shop'
match = re.match(pattern, str, re.I)
print(match)

print('起始位置', match.start())
print('结束位置', match.end())
print('匹配数据', match.group())

# 验证输入手机号是否为中国移动
pattern1 = r'(13[4-9]\d{8})|(15[01289]\d{8})$'
phone = '13134222222'
match1 = re.match(pattern1, phone)
if  match1 == None:
    print('不是有效的手机号', phone)
else:
    print('是有效的手机号码', phone)


# search() 从整个字符串搜索第一个匹配的值
pattern2 = r'md_\w' # 模式字符串
str2 = '项目MD_SHOP md_shop'
search2 = re.search(pattern, str, re.I)
print(search2)

# 验证是否出现危险字符
pattern3 = r'(黑客)|(抓包)|(监听)|(Trojan)'
about = '我是一名程序员,我喜欢看黑客方面的图书,想研究一下Trojan。'
search3 = re.search(pattern3, about)
if  search3 == None:
    print(about, '@ 安全')
else:
    print(about, '@ 危险')


# findall
pattern = r'md_\w' # 模式字符串
str = '项目名称MD_SHOP md_shop'
finall = re.findall(pattern, str, re.I)
print(finall)

        3. 替换字符串

                sub()

                        re.sub(pattern, replacement, string ,count, flags = re.IGNORECASE)

                                pattern 匹配模式-正则表达式

                                replacemet 要替换的字符串

                                string 原始字符串

                                count 匹配后替换最大次数 默认0

                                flags 匹配方式 

                                        re.i  不区分字母大小写

                                        re.A  让\w不匹配汉字

import re

# 替换危险字符
pattern3 = r'(黑客)|(抓包)|(监听)|(Trojan)'
about = '我是一名程序员,我喜欢看黑客方面的图书,想研究一下Trojan。'
sub = re.sub(pattern3, "xxx", about)
print('替换后:', sub)

        4. 分割字符串

                split() 返回列表

                        re.split(pattern, string, [maxsplit], flags)

                                pattern 匹配模式-正则表达式

                                string 要匹配的字符串

                                maxsplit 最大拆分次数,可选参数,不指定全部拆分

                                flags 匹配方式 re.i re.A

import re

pattern = r'[?|&]'
url = 'http://www.mddn.com/login.jsp?username="md"&password="mddn"'
result = re.split(pattern, url)
print(result)
  • 流程控制语句

        1. 流程控制语句

                1. 选择语句 if elif else

                2. 循环语句 while for

                3. 跳转语句 break continiu

                4. pass语句

        2. 选择语句

                if语句  python中没有switch语句

                1. if语句

print('今有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二,问几何?\n')

num = int(input('请输入您认为满足条件的数'))

if num % 3 == 2 and num % 5 == 3 or num % 3 == 2:
    print(num, "符合条件")


a = 10 
b = 5 
# 可以使用
if a > b : print(a)

               3. if..esle

print('今有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二,问几何?\n')
num = int(input('请输入您认为满足条件的数:'))
if num % 3 == 2 and num % 5 == 3 or num % 3 == 2:
    print(num, "符合条件")
else:
    print(num, "不符合条件")

                 3. if..esif...else语句

num = int(input('请输入送花朵数'))

if num == 1:
    print("送一朵花")
elif num == 3:
    print("送三朵花")
elif num == 10:
    print("送十朵")
else:
    print("送其他朵")

                4. if嵌套

print('为了安全不要喝酒')
proof = int(input('输入酒精含量'))
if proof < 20:
    print('不够成酒驾')
else:
    if 80 > proof >= 20:
        print("酒驾")
    else:
        print("醉驾")

                5. 使用and连接条件

print("考驾照啦")
age = int(input("请输入年龄:"))

if age >= 18 and age <= 70:
    print('符合条件')
else:
    print('不符合条件')


# 链式比较
if 18 <= age <= 70:
    print('符合条件')
else:
    print('不符合条件')

                6. 使用or连接条件

sales = int(input('请输入商品日销量'))

# 销量好的和销量差的都需要重点关注
if sales > 100 or sales < 10:
    print('重点关注')

                7. 使用not 关键字

data = None
if data is not None:
    print('有数据')
else:
    print('无数据')

        3. 循环语句

                1. for循环

                        for 迭代变量 in 对象:

                        range() 生成一系列连续整数

                                range(start, end, step)

                                        start: 起始值,非必填,默认0

                                        end: 结束值,必填,填写后不包含该值,结束值-1,

                                        step: 步长,非必填,默认1

                        xrange() python2中的函数,跟range()一样

# 计算1+2+3+....+100
result = 0
for i in range(101):
    result += i

print('计算结果', result)
                2. while循环

                        while 条件表达式:

a = 0
while a < 10:
    a += 1
    print('循环', a)
                3. 嵌套循环
# 打印99乘法表
for i in range(1, 10):  # 行数
    for j in range(1, i+1): # 输出行数中的列
        print(str(j) + "x" + str(i) + "=" +str(j*i) +'\t', end='')
    print("")
                4. break语句

                        break 跳出循环

# 三三剩二,五五剩三,七七剩二
for num in range(100):
    print(num)
    if num % 3 == 2 and num % 5 == 3 and num % 7 == 2:
        print("这个数是", num)
        break
                5. continue语句

                        continue 跳出一次循环

# 假设拍桌子99次
total = 99
for num in range(1, 100):
    if num % 7 == 0:
        continue
    else:
        string = str(num)
        if string.endswith('7'):
            continue
    total -= 1
print(total, '次')
  • 字典

        字典 dicttionary,java中的map

        key value的形式,列表不能作为字典的key,元组可以

        1. 创建字典

                dict = {'key':'value','key':'value','key':'value'......}

                zip(list1, list2) 将列表转换为字典,list1为key, list2为value, 返回zip对象

                dict(zip) zip对象转换为字典对象

                fromkeys() 创建值为空的字典

# 创建字典
word = {'che': '车', 'chen': '尘', 'cheng': '称', 'chi': '吃'}
print(word)

# 将列表转换为字典
key = ['che', 'chen', 'cheng', 'chi']
value = ['车', '尘', '称', '吃']
z = zip(key, value)
print(z)
# zip对象转换为字典对象
w = dict(zip(key, value))
print(w)

# 元组转换字典
name = ('绮梦', '冷一', '香凝', '黛蓝')
sign = ['水瓶座', '射手座', '双鱼座', '双子座']
c = {name: sign}
print(c)

# 创建空字典
dd = {}
print(dd)
dc = dict()
print(dc)


# 通过dict键值对创建字典
da = dict(绮梦='水瓶座', 冷一='射手座')
print(da)

# 通过dict->fromkeys() 创建值为空的字典
name_keys = ['绮梦', '冷一', '香凝', '黛蓝']
ks = dict.fromkeys(name_keys)
print(ks)

        2. 删除字典

                1. 删除字典

                        del 字典

                2. 只删除字典元素 - 清空字典

                        字典.clear()

        3. 访问字典

                1. 通过下标 - 下标指的是key并非索引

                2. 字典.get(key,[default]) 不指定返回None

name = ['绮梦', '冷一', '香凝', '黛蓝']
sign = ['水瓶座', '射手座', '双鱼座', '双子座']
d = dict(zip(name, sign))

# 通过下标
print(d['绮'])


# get()
print(d.get('冷一'))

# 指定默认值
print(d.get('冷', '查无此人'))

        4. 遍历字典

                items() 返回可比案例的元组列表

                keys() 返回健列表

                values() 返回值列表

sign = {'绮梦': '水瓶座', '冷一': '射手座', '香凝': '双鱼座', '黛蓝': '双子座'}

# 可遍历的元组列表
print(sign.items())

for key, value in sign.items():
    print(key, value)

# 获取健列表
k = sign.keys()
print(k)

# 获取值列表
v = sign.values()
print(v)

        5. 添加、修改、删除元素

                dict[key] = value  添加修改元素

                键必须唯一

                del dict[key] 删除元素 如不存在会抛出异常

sign = {'绮梦': '水瓶座', '冷一': '射手座', '香凝': '双鱼座', '黛蓝': '双子座'}

# 添加
sign['碧琪'] = '处女座'


# 修改
sign['冷一'] = '巨蟹座'

# 删除
del sign['冷一']

        6. 字典推导式

                {键表达式:值表达式 for}

import random

# 字典推导式
random_dict = {i: random.randint(1, 100) for i in range(1, 5)}
print(random_dict)

name = ['绮梦', '冷一', '香凝', '黛蓝']
sign = ['水瓶座', '射手座', '双鱼座', '双子座']

names = {i: j for i, j in zip(name, sign)}
  • 集合

        集合 set

        可变集合 set 用来保存不重复的元素,最好的应用是去重,集合也用{}来表示

        特点是自动去除重复数据,无序,不能通过索引来获取

                set() 空集合的创建

                set(list) 将列表转换为集合

        不可变集合 forzenset()

        1. 集合的创建

# 定义一个集合
set1 = {"水瓶座", '射手座', '双鱼座', '双子座'}  
print(set1)

# 创建空集合
set2 = set()

# 将列表和集合转换为set集合  set()方法
name = ['绮梦', '冷一', '香凝', '黛蓝', '绮梦']
print('列表', name)
set4 = set(name)
print('set集合', set4)

        2. 集合的添加和删除

                添加

                        setName.add(element)

                                element: 字符串,数字,bool, 不能使用列表元组等可迭代对象

                删除

                        remove() 删除集合元素

                        pop() 随机删除一个元素

                        clear() 清空集合

                        del 删除集合

# 添加元素
mr = set(['java', 'python', 'javascript', 'eleui'])
mr.add('php')
print(mr)


# 删除元素
mr.remove('php')
print(mr)

# 随机移除一个元素
temp = mr.pop()
print('随机移除的元素', temp)
print(mr)

# 清空集合
mr.clear()
print(mr)

# 删除集合
del mr

        3. 集合的交集、并集、差集运算

                & 交集

                | 并集

                - 差集

                ^ 对称差集

pyname = set(['绮梦', '冷一', '香凝', '黛蓝'])  # 选择pyhon
cname = set(['冷一', '灵玉', '子轩', '圣博'])   # 选择c
print('选择python', pyname)
print('选择c', cname)
# 交集运算
print('交集运算', pyname & cname) # 既选择pyhton又选择c
print('并集运算', pyname | cname) # 输出选课的所有学生名字 去除重复的
print('差集运算', pyname - cname) # 选择python但没有选择c语言的学生
  • 列表、元组、字典和集合的区别

        列表 、元组tuple、字典dict和集合set的区别

                    定义符号

        列表          []        可变        可重复        有序

        元组          ()        不可变        可重复        有序

        字典        {key:value}        可变        可重复        无序

        集合        {}        可变        不可重复        无序

  • 函数

        1. 函数的创建和调用

                def function([paramter_list]):

                        '''函数注释'''

                空函数可用pass关键字

# 创建函数
def filter_char(str):
    '''
    过滤危险字符,并将过滤后的字符
    str:要过滤的字符串
    无返回值
    '''
    pattern = r'(黑客)|(抓包)|(监听)|(Trojan)' # 模式字符串
    sub = re.sub(pattern, '***', str)
    print(sub)

# 创建空函数
def empty():
    pass

# 函数调用
about = '我是一名程序员,我喜欢看黑客方面的图书,想研究一下Trojan。'
filter_char(about)

        2. 形参和实参

                形式参数和实际参数

                        值传递: 不可变参数

                        引用传递: 可变参数

# 定义函数=有参
def demo(obj):
    print('原值', obj)
    obj += obj

# 值传递
mot = '唯有python'
print('函数调用前', mot)
demo(mot)
print('函数调用后', mot) # 值并未有任何改变

# 引用传递
list = ['绮梦', '冷一一', '香凝', '黛蓝']
print('函数调用前', list)
demo(list)
print('函数调用后', list)

        3. 位置参数

                必须按照定义时的个数和顺序进行参数传递,也成为必备参数

def bmi(person, height, weight):
    '''
    根据身高体重计算bmi指数
    :param person: 姓名
    :param height: 身高
    :param weight: 体重
    :return:
    '''
    print(person+'您的身高为:' + str(height) + '米' + '体重为' + str(weight))
    bmi = weight / (height ** 2)
    print(person, '您的bmi指数为:', bmi)
    if bmi < 18.5:
        print(person, '体重过轻')
    elif 18.5 >= bmi < 24.9:
        print(person, '正常范围')
    elif 24.9 >= bmi < 29.9:
        print(person, '体重过重')
    elif 29.9 >= bmi:
        print(person, '体重肥胖')

bmi('路人甲', 1.83, 60)

        4. 关键字参数

                使用形式参数的名字来确定要输入的参数值

def bmi(person, height, weight):
    '''
    根据身高体重计算bmi指数
    :param person: 姓名
    :param height: 身高
    :param weight: 体重
    :return:
    '''
    print(person+'您的身高为:' + str(height) + '米' + '体重为' + str(weight))
    bmi = weight / (height ** 2)
    print(person, '您的bmi指数为:', bmi)
    if bmi < 18.5:
        print(person, '体重过轻')
    elif 18.5 >= bmi < 24.9:
        print(person, '正常范围')
    elif 24.9 >= bmi < 29.9:
        print(person, '体重过重')
    elif 29.9 >= bmi:
        print(person, '体重肥胖')

bmi(person='路人乙', weight=60, height=1.5)

        5. 为参数设置默认值

                如果要为参数设置默认值,此参数必须要放到最后面

                查看方法默认值

                        方法名.__defaults__

                定义函数的参数时,为形式参数设置默认值不要指向不可变对象

def bmi(height, weight, person='路人已'):
    '''
    根据身高体重计算bmi指数
    :param person: 姓名
    :param height: 身高
    :param weight: 体重
    :return:
    '''
    print(person+'您的身高为:' + str(height) + '米' + '体重为' + str(weight))
    bmi = weight / (height ** 2)
    print(person, '您的bmi指数为:', bmi)
    if bmi < 18.5:
        print(person, '体重过轻')
    elif 18.5 >= bmi < 24.9:
        print(person, '正常范围')
    elif 24.9 >= bmi < 29.9:
        print(person, '体重过重')
    elif 29.9 >= bmi:
        print(person, '体重肥胖')

bmi(1.5, 60)

# 查看方法默认值
print('查看方法默认值', bmi.__defaults__)

        6. 可变参数

                个数不固定的参数 0-n个参数

                *parameter 可以接收任意多个实际参数,并放到一个元组中

                **paramter 接收任意多个类似关键字参数一样显式赋值的实际参数,并将其放到一个字典中

                实际调用时,传递参数使用*param, * 为解包,调用时对于可迭代对象进行解包,使其中的元素能作为独立的 参数传递给参数

# *parameter
def coffee(*coffee_name): # 输出咖啡名称
    print('\n我喜欢的咖啡有:')
    for name in coffee_name:
        print(name)


# 调用
coffee('摩卡', '拿铁', '卡布奇诺')

list1 = ['摩卡', '拿铁', '卡布奇诺']
# *list1  *为解包 调用时用于对可迭代对象进行解包 是其中的元素能作为独立的参数传递给函数
coffee(*list1)

# 可变参数
def bmi_a(*person):
    '''
    升级可变参数 姓名 身高m 体重kg
    :param person:
    :return: 可变参数 姓名 身高m 体重kg
    '''
    for list_person in person:
        for item in list_person:
            person = item[0]
            height = item[1]
            weight = item[2]
            print(person + '您的身高为:' + str(height) + '米' + '体重为' + str(weight))
            bmi = weight / (height ** 2)
            print(person, '您的bmi指数为:', bmi)
            if bmi < 18.5:
                print(person, '体重过轻')
            elif 18.5 >= bmi < 24.9:
                print(person, '正常范围')
            elif 24.9 >= bmi < 29.9:
                print(person, '体重过重')
            elif 29.9 >= bmi:
                print(person, '体重肥胖')


list_w = [['绮梦', 1.70, 60], ['灵玉', 1.80, 65], ['张三', 1.40, 80]]
list_m = [['李四', 1.50, 60], ['王五', 1.10, 100]]
bmi_a(list_w, list_m)


# **parameter
def sign(**sign):
    print()
    for key, value in sign.items():
        print(key + '的星座是 ' + value)

sign(绮梦='水瓶座', 冷一='射手座')
sign(香凝='双鱼座', 张三='巨蟹座', 王五='天蝎座')
sign_dict = {'绮梦': '水瓶座', '冷一': '射手座','香凝': '双鱼座', '张三': '巨蟹座', '王五': '天蝎座'}
sign(**sign_dict)

        7. 返回值

                retuen 返回值,一个或者多个,多个值就是一个元组

     

def fun_checkout(money):
    '''
    计算商品合计金额并进行折扣处理
    :param money: 商品金额列表
    :return: 商品合计金额和折后金额
    '''
    money_old = sum(money) # 合计金额
    money_new = money_old
    if 500 <= money_old < 1000: # 享受9折优惠
        money_new = '{:2f}'.format(money_old * 0.9)
    elif 1000 <= money_old <= 2000:
        money_new = '{:2f}'.format(money_old * 0.8)
    elif 2000 <= money_old <= 3000:
        money_new = '{:2f}'.format(money_old * 0.7)
    elif money_old <= 3000:
        money_new = '{:2f}'.format(money_old * 0.7)

    return money_old, money_new # 返回总金额和折扣后金额

print('\n开始计算.......、\n')
list_money = []
while True:
    input_money = float(input('请输入商品金额,输入0代表结束'))
    if int(input_money) == 0:
        break
    else:
        list_money.append(input_money)
        money = fun_checkout(list_money)



print('合计金额', money[0], '应付金额', money[1])

        8. 变量作用域

                global 修饰局部变量改变为全局变量

                全局变量不能在函数体内改变全局变量的值,如果改变的话会被重新定义为局部变量,改变的是局部变量的值

# 局部变量
def fun_demo():
    message = '局部变量'
    print(message)


msg = '全局变量'

def fun_demo1():
    global msg  # 定义全局变量
    msg = '函数体内改变'
    print('全局变量-函数体内', msg)

fun_demo1()
print('全局变量-函数体外', msg)

        9. 匿名函数

                只能使用一次,使用lambda表达式

                lambda

                        result = lambda [arg1 [, arg2, ..., argn]] : expression(表达式)

                                expression 中不能出现for while等

import math

# 正常方法
def circlearea(r): # 计算园的面积
    return math.pi * (r**2)

r = 10
area = circlearea(r)
print('半径为', r, '的圆的面积为', area)

# lambda
r = 10 # 半径
result = lambda r : math.pi * (r**2)
print(result)


# 按照打折折扣排序
book_info = [('不一样的卡梅拉', 22.50, 120), ('零基础学安卓', 65.10, 89.80),
             ('摆渡人', 23.40, 36.00), ('福尔摩斯', 22.50, 128)] # 商品列表

print('爬取到的商品信息\n', book_info, '\n')

# 排序
book_info.sort(key=lambda x: (x[1], x[1]/x[2])) # 指定排序规则
print('排序后的商品信息\n', book_info, '\n')
  •  常用内置函数

        help() 查看函数模块的用途

        id() 查看对象内存地址

        oct() 十进制转八进制

        round() 四舍五入

                遵循靠近0的元组 0.5 0位舍入结果是0

        python官方api文档

                安装路径/doc/.chm

  • 面向对象

                对象和类

                        封装 继承 多态

        1. 定义类

                class ClassName():

                        '''类的帮助信息'''

class Geeses():
    '''大雁类'''
    pass

        2. 创建类的实例

                创建对象

                        ClassName(parameterList)

                                parameterList 可选参数,如果创建类时没有创建init()或者init()内只有self一个参数的话可以省略,否则就是init方法内的参数

class Geese:
    '''大雁类'''
    pass

# 创建类实例
wildGeese = Geese()
print(wildGeese)

        3. init方法

                init() 相当于java中的构造方法

                初始化的作用

                python和java不同,java中可以有多个构造方法,python中只能有一个

                self参数必须作为第一个,有其他参数在后面进行添加,self指向实例本身的引用,通过他可以访问类中的对象和属性

class Geesewc:
    '''大雁类'''
    def __init__(self): # 定义构造方法
        print('我是大雁类:')


class Geesee:
    '''大雁类'''
    # self参数必须作为第一个 有其他参数在后面进行添加 self指向实例本身的引用 通过他可以访问类中的对象和属性
    def __init__(self, beak, wing, claw): # 定义构造方法
        print('我是大雁类我有以下特征:')
        print(beak)
        print(wing)
        print(claw)

# 无参
wildGeeseWc = Geesewc()

# 有参
beak1 = '喙的基部较高,长度和头的长度几乎相等'
wing1 = '翅膀长而尖'
claw1 = '爪子是浦状的'
wildGeese = Geesee(beak1, wing1, claw1)

        4. 创建类的成员并访问

                实例方法 - 方法

                        创建实例

                        def functionName(self, parameterList):

                                block

                                self 必须要的参数

                        访问

                        instanceName.functionName(paramList)

                        类的实例名称.实例方法名称

                数据成员 - 属性

                        类属性,定义在类中,在方法体外的属性,在所有实例之间共享值

                                访问:类名.属性名

                        实例属性,定义在类中的方法,只作用与当前实例,只能通过类的对象进行访问

                                访问:类对象.属性名

class Geesef:
    '''大雁类'''
    def __init__(self, beak, wing, claw):  # 定义构造方法
        print('我是大雁类我有以下特征:')
        print(beak)
        print(wing)
        print(claw)

    # 创建类实例方法
    def fly(self, state='本身就会飞'):  # 飞行方法
        print('飞行状态:', state)


beak1 = '喙的基部较高,长度和头的长度几乎相等'
wing1 = '翅膀长而尖'
claw1 = '爪子是浦状的'
wildGeese = Geesef(beak1, wing1, claw1)
wildGeese.fly('起飞')
wildGeese.fly()


class Geesed:
    neck = '脖子较长'  # 类属性 脖子
    wing = '振翅频率高'  # 翅膀
    leg = '腿'

    def __init__(self):  # 定义构造方法
        print('我是大雁类我有以下特征:')
        print(Geesed.neck)
        print(Geesed.wing)
        print(Geesed.leg)


geed = Geesed()


class dayansl:
    def __init__(self):
        self.neck = '脖子较长' # 实例属性
        self.wing = '振翅频率高'
        self.leg = '腿'
        print('我是大雁类我有以下特征:')
        print(self.neck)  # 访问实例属性
        print(self.wing)
        print(self.leg)

dayansl = dayansl()
# 访问实例独享
print(dayansl.neck)
# 修改
dayansl.leg = '我是腿'
print(dayansl.leg)

        5. 访问限制

                java中提供了修饰符,pyhton中没有

                _foo: protected,保护,只允许类本身加子类访问

                __foo: private,私有类型,只允许类本身访问,类的实例名._类名__xxx

                __foo__: 系统定义

                pyhton中对以下划线开头的属性进行了变形,形成了_类型_foo(只发生在类的定义时,方法执行时不会采用这个变形)

class Swan:
    '''天鹅类'''
    _neck_swan = '天鹅脖子很长' # 受保护类型的属性
    __neck_sy = '私有天鹅'  # 私有类型
    def __init__(self):
        print('init()', Swan._neck_swan) # 访问保护类型属性
        print('init()', Swan.__neck_sy) # 访问私有类型
    def my(self):
        print('my()', Swan.__neck_sy)


swan = Swan()
print(swan._neck_swan) # 通过实例名访问保护类型属性
print(swan._Swan__neck_sy) # 访问私有类型
swan._Swan__neck_sy = '天鹅私有修改' # 修改私有类型
print(swan._Swan__neck_sy) # 访问私有类型

swan.my()

        6. proterty装饰器

               property 访问计算后所得的值

               @property装饰器,把方法转换成属性,可以通过排方法名访问方法,不用添加括号,不不可以重新赋值

                        @property

                        def method(self):

                                block

class Rect:
    def __init__(self,width, height):
        self.width = width
        self.height = height

    @property
    def area(self):
        return self.width * self.height # 计算矩形面积

rect = Rect(10, 10)
print('面积为', rect.area)

                还可用于创建不能修改,只读的属性

class TvShow:
    def __init__(self, show):
        self.__show=show
    @property
    def show(self):
        return self.__show

tvshow = TvShow('正在播放渣浪2')
print('默认', tvshow.show) # 获取属性值
# 下列代码修改报错
# tvshow.show='红海行动'



class TvShows:
    list_film = ['战狼2', '红海行动', '西游记女儿国', '熊出没']
    def __init__(self, show):
        self.__show=show
    @property
    def show(self):
        return self.__show
    @show.setter
    def show(self,value):
        if value in TvShows.list_film:
            self.__show= '点播' + value
        else:
            self.__show='不存在'

tvshows = TvShows('战狼2')
print('正在播放' + tvshows.show)
print('您可以从', TvShows.list_film ,'中点播')
tvshows.show = '红海行动'
print('修改后' + tvshows.show)
  • 继承

                class ClassName(baseClassList):

                        baseClassList: 要继承的父类,默认继承object,当子类继承父类,子类就继承了父类的的实例方法和属性

class Fruit:
    color = '绿色' # 类属性
    def harvest(self, color):
        print('水果是:', color)  # 输出形式参数color
        print('水果已经收获')
        print('水果原来的颜色', Fruit.color) # 输出类属性

class Apple(Fruit): # 继承Fruit类
    color = '红色'
    def __init__(self):
        print('我是苹果')

class Orange(Fruit): # 继承Fruit类
    color = '橙色'
    def __init__(self):
        print('我是橘子')

# 苹果类
apple = Apple() # 创建苹果类实例
apple.harvest(apple.color)  # 调用父类的harbest方法
# 橘子类
orange = Orange()
orange.harvest(Orange.color)

                1. 方法重写

class Fruit: # 父类 - 基类
    color = '绿色' # 类属性
    def harvest(self, color):
        print('水果是:', color)  # 输出形式参数color
        print('水果已经收获')
        print('水果原来的颜色', Fruit.color) # 输出类属性

class Apple(Fruit): # 继承Fruit类
    color = '红色'
    def __init__(self):
        print('我是苹果')
    # 重写方法
    def harvest(self, color):
        print('苹果是:', color)  # 输出形式参数color
        print('苹果已经收获')
        print('苹果原来的颜色', Fruit.color) # 输出类属性

class Orange(Fruit): # 继承Fruit类
    color = '橙色'
    def __init__(self):
        print('我是橘子')

    # 重写方法
    def harvest(self, color):
        print('橘子是:', color)  # 输出形式参数color
        print('橘子已经收获')
        print('橘子原来的颜色', Fruit.color) # 输出类属性

# 苹果类
apple = Apple() # 创建苹果类实例
apple.harvest(apple.color)  # 调用父类的harbest方法
# 橘子类
orange = Orange()
orange.harvest(Orange.color)

                2. 子类调用父类init()

                        默认子类创建init()后不会自动调用父类的init(),子类不定义构造方法,就会默认调用父类的构造方法

                        super.__init__(self)

class Fruit: # 父类 - 基类
    def __init__(self,color='绿色'):
        Fruit.color=color
        print('水果类init')
    def harvest(self, color):
        print('水果是:', color)  # 输出形式参数color
        print('水果已经收获')
        print('水果原来的颜色', Fruit.color) # 输出类属性

class Apple(Fruit): # 继承Fruit类
    color = '红色'
    def __init__(self):
        # 调用基类的构造函数
        super().__init__()
        print('我是苹果')
    # 重写方法
    def harvest(self, color):
        print('苹果是:', color)  # 输出形式参数color
        print('苹果已经收获')
        print('苹果原来的颜色', Fruit.color) # 输出类属性

class Sapodille(Fruit): # 继承Fruit类
    def __init__(self, color):
        # 调用基类的构造函数
        print('我是人参果')
        super().__init__(color)

    # 重写方法
    def harvest(self, color):
        print('人参果是:', color)  # 输出形式参数color
        print('人参果已经收获')
        print('人参果原来的颜色', Fruit.color) # 输出类属性

# 苹果类
apple = Apple() # 创建苹果类实例
apple.harvest(apple.color)  # 调用父类的harbest方法
# 人参果
sapodille = Sapodille('白色')
sapodille.harvest('金黄色')
  • 模块

                把能够实现某一特定功能的代码放置在一个文件夹中作为一个模块

                使用模块的好处

                        1. 避免函数名和变量名冲突

                        2. 更容易查找代码

                        3. 提交代码重永兴

                        4. 有选择的使用

                标准模块-标准库

                        random、math、sys、tkinter、decimal、os、logging、urllib、json、calendar、re、shutil、datetime

        1. 创建模块

# 模块-model包内 模块名BMI
def bmi(height, weight, person='路人已'):
    '''
    计算单人BMI
    :param person: 姓名
    :param height: 身高
    :param weight: 体重
    :return:
    '''
    print(person+'您的身高为:' + str(height) + '米' + '体重为' + str(weight))
    bmi = weight / (height ** 2)
    print(person, '您的bmi指数为:', bmi)
    if bmi < 18.5:
        print(person, '体重过轻')
    elif 18.5 >= bmi < 24.9:
        print(person, '正常范围')
    elif 24.9 >= bmi < 29.9:
        print(person, '体重过重')
    elif 29.9 >= bmi:
        print(person, '体重肥胖')

def bmi_a(*person): # 可变参数
    '''
    计算多个人
    :param person:
    :return: 可变参数 姓名 身高m 体重kg
    '''
    for list_person in person:
        for item in list_person:
            person = item[0]
            height = item[1]
            weight = item[2]
            print(person + '您的身高为:' + str(height) + '米' + '体重为' + str(weight))
            bmi = weight / (height ** 2)
            print(person, '您的bmi指数为:', bmi)
            if bmi < 18.5:
                print(person, '体重过轻')
            elif 18.5 >= bmi < 24.9:
                print(person, '正常范围')
            elif 24.9 >= bmi < 29.9:
                print(person, '体重过重')
            elif 29.9 >= bmi:
                print(person, '体重肥胖')

        2. import导入模块

                import 模块名 as 别名

                from 模块名 import 方法名1,方法名2

                如导如的方法过多 方法名可以为*

                dir() 可以查看内部定义了哪些函数

                导入两个包含同名函数的模块可用使用as进行修改别名,否则直接调用会有意想不到的惊喜

                下方调用模块代码请看1. 创建模块

import module.BMI as bmi


bmi.bmi(1.8, 70, '张三')
from module.BMI import *

# 查看内部定义函数
print(dir())

# 模块函数调用
bmi(1.87, 50)

bmi_a([('张三', 1.87, 60)])

        3. 模块搜索目录

                使用标准模块sys中的path变量来获取

                1. 临时添加要查找的目录

                        sys.path.append('路径')

                        关闭后失效

                2. 添加.path文件

                        在python安装目录下添加*.path

                3. 在python path环境变量中添加

                        在系统变量中添加PYTHPATH路径为保存模块的路径

                

import sys
# 临时添加要查找的目录
sys.path.append("F:\\python-works\\python_basis\\day6\\module")
# 下面就可以直接导入了不需要加路径
import BMI
  • 主程序

        if __name__ == '__main__':

        __name__ 模块名称变量

        当程序在顶级模块运行时,他的值为__main__

if __name__ == '__main__':
    pass

        包内包含__init__.py

        避免模块名重名引发的冲突

        import 完整包名+模块名

        form 完整包名 import 模块名

        from 完整包名.模块名 import 定义名

  • 标准模块

        导入和使用标准模块

import random


# 生成随机验证码

if __name__ == '__main__':
    checkcode = ''  # 验证码
    for i in range(4):
        # 生成一个0^3中的一个数
        index = random.randrange(0, 4)
        if index != i and index + 1 != i:
            # 生成 a-z 小写字母(97 - 122) ASCII
            checkcode += chr(random.randint(97, 122))
        elif index +1 == i:
            # A-Z大写紫米
            checkcode += chr(random.randint(65, 90))
        else:
            checkcode += str(random.randint(1, 9))

    print(checkcode)
  • 第三方模块

        1. https://pypi.org

        2. pip

                pip <command> [moduleName]

                        command: install uninstall list

        导入顺序

                1. 标准模块

                2. 第三方模块

                3. 自定义模块

  • 文件

        File对象

        1. 创建、打开、关闭文件

                file = open(fileName[, mode[, buffering]])

                        fileName: 创建或者要打开的文件名

                        buffering: 0:不缓存 1:缓存 大于1:缓冲区大小

                        mode: 文件的打开模式

                                r = 只读

                                r+ =  读写 从头覆盖原内容

                                w = 只写 文件不存在创建

                                w+ = 打开文件后,先清空原内容,使其成为空文件,对这个空文件有读写权限

                                a = 追加 文件不存在创建 

                                a+ = 读写,文件存在指针放末尾,否则新建读写

                                b = 二进制

                                rb = 二进制打开文件 只读

                                rb+ = 二进制打开,读写,文件的指针在文件的开头,常用非文本文件,图片声音等

                                wb = 二进制,只读,常用于图片声音等非文本

                                wb+ = 二进制,读写,绯闻班

                                ab = 二进制,追加,文件存在则指针放在文件末尾,否则创建新文件用于写入

                                ab+ = 二进制,追加,文件存在指针放末尾,否则新建文件读写

                                可以和+进行组合

                关闭文件

                        file.close() 关闭文件

                        file.closed 查看文件是否被关闭 Flase没有关闭 True 关闭

# 创建和打开文件 
file_img = open('file/123.jpg', 'rb') # 二进制打开图片
print(file_img)

# 关闭文件
if not file_img.closed:
    print('文件未关闭', file_img.closed)
    file_img.close()
    print('文件已关闭', file_img.closed)

        2. with 打开文件

                使用with打开文件后会自动关闭

                with expression as target:

                        expression: 表达式 指定要打开文件的open()

                        target: 指定变量 保存打开的结果

# 创建和打开文件  open
with open('file/status.txt', 'r', encoding='utf-8') as file:
    pass

print('文件是否被关闭', file.closed)

        3. 文件写入

                write() 文件写入 返回写入量

                        file.write(string)

                flush() 刷新缓冲区进行写入

                        file.flush()

                writelines() 写入字符串列表 不会换行

                        file.writelines()

file = open('file/message.txt', 'w', encoding='utf-8')
print('\n即将显示\n')
file.write('蚂蚁呀嘿')  # 写入时如没关闭文件会容易出现不显示的问题
# file.close()
file.flush() # 刷新缓冲区


file = open('file/message.txt', 'w', encoding='utf-8')
file.write('你使用了一张加速卡,小鸡撸起袖子开始双手吃饲料,进食速度大大加快\n')
print('写入了一条动态')
# file.writelines()
file.close()

str_list = ['姚明', '博尔特', '姆巴佩', '张一鸣']
with open('file/message.txt', 'w', encoding='utf-8') as file:
    file.writelines([line + '\n' for line in str_list])

        4. 读取文件

                read() 读取指定字符串

                        file.read([size])

                                size: 读取的个数,不指定默认全部读取

                                读取文件前提:打开文件模式只能是r或者r+拥有读取权限的

                                没一个字母汉字数字等都占一个字符

                seek() 将指针移动到指定位置

                        file.seek([size])

                                size:英文字母数字占一个字符,汉字根据编码不同所占数不同

                                汉字: gbk 2字符 utf8 3字符

                                TODO 英文半角符号就占用一个字符!!!!!!!!!!踩过坑

                readLine() 读取一行

                        file.readline()

                readLines() 读取全部行

                        file.readLines()

with open('file/message.txt', 'r+', encoding='utf-8') as file:
    file.seek(30)
    content = file.read(2)
    print(content)

# 逐行读取
with open('file/tansuo.txt', 'r', encoding='utf-8') as f:
    print('=' * 10)
    num = 0
    while True:
        num += 1
        line = f.readline()
        if line == '':
            break
        print(num, line, end='\n')
print('over')


# 读取全部行
with open('file/tansuo.txt', 'r', encoding='utf-8') as f:
   message = f.readlines()
   print(message)
   for line in message:
       print(line)
print('over')
  • 目录

        os模块: 内置与操作系统功能和文件系统相关的模块,该模块中的雨具执行结果通常与操作系统有关,不同操作系统运行结果不同

        1. os模块和os.path模块

                os.path是os的子模块,只需要导入os模块即可

                        os.name 获取操作系统名称,返回 'nt' = windows 'posix' = linux or macos

                        os.linesep 获取当前系统换行符

                        os.sep 获取当前系统路径所使用分隔符

                        getcwd() 返回当前的工作目录

                        listdir(path) 返回指定路径下的文件和目录信息

                        mkdir(path,[,mode]) 创建目录

                        makedits(path/path..., [, mode]) 创建多级目录

                        rmdir(path) 删除目录

                        removedirs(path1,path2...)  删除多级目录

                        chdir(path) 把path设置为当前工作目录

                        walk(top, [topdown[, oneerror]]) 遍历目录树,返回一个元组,包含所有路径名,所有目录列表和文件列表三个元素

                os.path 目录相关函数

                        abspath(path) 获取文件或目录绝对路径

                        exists(path) 判断目录是否存在,存在返回True,不存在返回False

                        join() 将目录与目录或者文件名拼接起来

                        splitext() 分割文件名和扩展名

                        basename(path) 从一个目录中提取文件名

                        dirname(path) 从一个路径中提取文件路径,不包含文件名

                        isdir() 判断是否是路径

import os

print(os.name) # 获取操作系统名称
print(os.linesep) # 获取当前系统换行符
print(os.sep) # 获取当前系统路径所使用分隔符

        2. 路径

                相对路径:相对于当前文件的路径

                绝对路径:完整文件路径

                getcwd() 获取当前目录

                os.path.abspath(path) 获取绝对路径

                        path 相对路径

                os.path.join(path1, path2...) 拼接路径

                        不会检查路径是否真实存在

                如果出现多个绝对路径,以最后一个出现的为准

                路径尽量使用 r'路径'

import os
print(os.getcwd()) # 获取当前目录
# 相对路径
with open(r'file/message.txt', 'r', encoding='utf-8') as f:
    print(f.read())

print(os.path.abspath(r'file/message.txt'))


# 拼接路径 不会检查路径是否存在
path = os.path.join(r'F:\python-works\python_basis\day7', r"file\message.txt")
print(path)
if os.path.exists(path):
    print('存在')

        3. 判断目录是否存在

                os.path.exists()

import os

# 判断目录是否存在
print(os.path.exists(r'file'))

# 判断文件是否存在
print(os.path.exists(r'file/123.jpg'))

        4. 创建目录

                mkdir() 创建目录

                        os.mkdir(path,mode=0o755)

                                path: 路径

                                mode: 默认值00777,在unix无效

                makedirs()  创建多级目录

                        os.makedirs(path, mode=0o777)

import os

if not os.path.exists('file/demo'):
    os.mkdir('file/demo')
else:
    print('该目录存在')


# 使用递归函数创建多级目录
def mkdir(path): # 创建递归函数
    if not os.path.isdir(path): # 判断是否是路径
        mkdir(os.path.split(path)[0])
    else:
        return
    os.mkdir(path)

mkdir(r'file/demo/re/demo/test')

# 创建多级目录
os.makedirs(r'file/demo/re/demo/test')

        5. 删除目录

                rmdir()

                        os.rmdir(path)

                                目录不为空不可删除

                rmtree(path) 删除不为空的目录

                        import shutil

                        shutil.rmtree()

import os
import shutil

# F:\python-works\python_basis\day7\file\demo\re\demo
# 删除目录
if os.path.exists(r'file\demo\re\demo'):
    # os.rmdir(r'file\demo\re\demo')
    # 删除非空目录
    shutil.rmtree(r'file\demo\re\demo')
    print('删除成功')
else:
    print('目录不存在')

6. 遍历目录

        win、unix系统

        walk()

                os.walk(top[, topdown][, onerror][, followlinks])

                        top:必选参数要遍历内容的根目录

                        topdown: 可选参数,指定遍历顺序 True自上而下遍历-先根目录后子目录,False自下而上-先遍历子目录

                onerror: 错误处理方式,默认忽略

                followlinks: true 指定在支持的操作系统上访问由符号链接(软连接)指向的目录,软连接相当于win中的快捷方式

                返回值:元组生成器对象(dirpath, dirnames, filenames)

                        dirpath: 当前遍历的路径-字符串

                        dirnames: 当前路径下包含的子目录 - 列表

                        filenames: 当前路径下所包含的文件 - 列表

import os

path = r'G:\照片'
print('【', path, '】', '目录下包含的文件和目录')
for root, dirs, files in os.walk(path, topdown=True):
    for filename in dirs:
        print(os.path.join(root, filename)) # 输出遍历到的目录
    for filename in files:
        print('\t', os.path.join(root, filename))

        7. 删除文件

                remove(path)

                        os.remove()

import os

if os.path.exists(r'file/demo/re/test.txt'):
    os.remove(r'file/demo/re/test.txt')
    print('删除完成')
else:
    print('文件不存在')

        8. 重命名文件和目录

                rname()

                        os.rname(src, dst)

                                src: 要进行重名的目录或者文件路径

                                dst: 重命名之后的目录或者文件名

import os

scr = r'file/demo/re/message.txt'
dst = r'file/demo/re/m.txt'
if os.path.exists(scr):
    os.rename(scr, dst)
    print('修改完成')
else:
    print('目录或文件不存在')

        9. 获取文件基本信息

                stat()

                        os.stat(path)

                                st_ctime 创建日期

                                st_mtime 修改日期

                                st_size 文件大小

                                st_mode 保护模式

                                st_ino 索引号

                                st_atime 最后一次访问时间

import os
import time


# 格式化时间
def formatTime(longtime):
    '''格式化时间'''
    return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())

# 格式化文件大小
def fotmatByte(number):
    '''格式化文件大小'''
    for (scale, label) in [(1024*1024*1024, 'GB'), (1024*1024, 'MB'), (1024, 'KB')]:
        if number >= scale: # 大于等于1kb
            return '%2f %s' % (number*1.0/scale, label)
        elif number == 1: # 小于1kb
            return '1字节'
        else:
            byte = '%2f' % (number or 0)
    return (byte[:-3] if byte.endswith('.00') else byte) + '字节'



fileinfo = os.stat(r'file/123.jpg')
print('文件完整路径', os.path.abspath('file/123.jpg'))
print('索引号', fileinfo.st_ino)
print('设备名', fileinfo.st_dev)
print('文件大小', fileinfo.st_size)
print('文件大小', fotmatByte(fileinfo.st_size))
print('最后一次访问日期', formatTime(fileinfo.st_atime))
print('最后一次修改日期', fileinfo.st_mtime)
print('最后一次状态改变的时间', fileinfo.st_ctime)
  • 数据库

        1. 连接数据库对象

                SQLite模块:sqlite3

                MySQL模块:pymsql

                连接对象

                        connect() 生成连接对象-connection对象

                                dsn: 数据源

                                user: 用户名

                                password: 密码

                                host: 主机名

                                database: 数据库名

                                charset: 编码格式

                                cursorclass: 游标类

                connection对象常用方法

                        cursor() 获取游标对象,操作数据库,指定dml,调用存储过程等

                        commit() 提交事务

                        rollback() 回滚事务

                        close() 关闭数据库连接

        2. 游标对象

                Cursor对象

                        Connection.cursor()

                Cursor对象常用方法

                        callproc(proname,[, paramters]) 调用存储过程

                        close() 关闭游标对象

                        excute(operation[, paramters]) 执行数据库操作,sql语句或者数据库命令

                        excutemany(operation, seq_of_params) 用于批量操作

                        fetchone() 获取查询结果集中的下一条记录

                        fetchmany(size) 获取指定数量的记录

                        fetchall() 获取结果集所记录

                        nextset() 跳转下一个可用的结果集

        3. 创建数据库文件

                SQLite 是文本数据库,内置sqlite3

import sqlite3

#创建连接对象
conn = sqlite3.connect('mddn.db')

# 创建游标
cursor = conn.cursor()

# 执行sql
cursor.execute('create table user (id int(10) primary key, name varchar(20))')

# 关闭游标
cursor.close()

# 关闭连接
conn.close()

        4. 操作SQLite

import sqlite3

# 创建连接对象
conn = sqlite3.connect('mddn.db')

# 创建游标
cursor = conn.cursor()

# 执行sql
sql = 'insert into user (id,name) values (?, ?)'
# cursor.execute(sql,(2, 'xiaoming'))

# 新增多条语句
# data = [(3, 'lisi'), (4, 'wangwu'), (5, 'bobi')]
# cursor.executemany(sql, data)

# 查询数据
sql = 'select * from user where id > 3'
cursor.execute(sql)
# 获取单条
# res1 = cursor.fetchone()
# print(res1)

# 获取指定条数
# res1 = cursor.fetchmany(2)
# print(res1)

# 获取所有
# res1 = cursor.fetchall()
# print(res1)


# 修改用户信息 需要提交事务
# sql = 'update user set name = ? where id = ?'
# cursor.execute(sql, ('MR', 1))

# 删除用户信息 不需要提交事务
sql = 'delete from user where id = ?'
cursor.execute(sql, (1,))


# 关闭游标
cursor.close()

# 提交事务 - 查询语句不需要事务
conn.commit()

# 关闭连接
conn.close()

        5. 连接mysql

# 导入PyMysql模块
import pymysql

# 调用connect() 创建连接对象
conn = pymysql.connect(host='127.0.0.1', user='root', password='123456', db='test', charset='utf8')

# 调用cursor()  创建cursor对象
cursor = conn.cursor()

# 执行sql语句
sql = 'select * from jimu_dict'
cursor.execute(sql)
data = cursor.fetchall()
print(data)

# 关闭连接
cursor.close()
# 关闭数据源
conn.close()

        6. 创建数据库表

# 导入PyMysql模块
import pymysql

# 调用connect() 创建连接对象
conn = pymysql.connect(host='127.0.0.1', user='root', password='123456', db='test', charset='utf8')

# 调用cursor()  创建cursor对象
cursor = conn.cursor()

# 执行sql语句
cursor.execute('drop table if exists books')    # 如果数据库表存在则删除
sql = """
create table books(xxx)
"""
sql = 'select * from jimu_dict'
cursor.execute(sql)
data = cursor.fetchall()
print(data)

# 关闭连接
cursor.close()
# 关闭数据源
conn.close()

        7. 操作数据库表

                sqlite占位符为?

                pymysql占位符为%s

# 导入PyMysql模块
import pymysql

# 调用connect() 创建连接对象
conn = pymysql.connect(host='127.0.0.1', user='root', password='123456', db='test', charset='utf8')

# 调用cursor()  创建cursor对象
cursor = conn.cursor()


# res = cursor.fetchall()
# print(res)

try:
    # 执行sql语句
    sql = 'insert into books(name,category,price,publish_time) values(%s,%s,%s,%s)'
    data = [('0基础', 'python', 79.80, '2018-11-11'), ('java基础', 'java', 22.80, '2018-12-12'),
            ('web基础', 'web', 99.80, '2024-11-11')]
    cursor.executemany(sql, data)
    conn.commit()
except:
    conn.rollback()

# 关闭连接
cursor.close()
# 关闭数据源
conn.close()
  • 进程

        1. 使用multiprocessing模块进程

                os.fork() 不支持win, 只支持linux

                multiprocessing模块process类

                Process([group[, target[, name[, args[, kwargs]]]]])

                         group: 参数未使用,始终为None

                        targer: 表示当前进程启动时执行的可调用对象

                        name: 当前进程实例的别名

                        args: 表示传递给target函数的参数元组

                        kwargs: 表示传递给target函数的参数字典

                is_alive() 判断进程实例是否还在执行

                join([timeout]) 是否等待进程实例执行结束,或等待多少秒

                start() 启动进程实例

                run()  如果没指定target参数,对这个对象调用start()时,就执行对象中的run()

                timeinate() 不管任务是否完成,立即终止

                属性

                name: 当前进程实例别名,默认为Process-N N为从1开始递增的整数

                pid: 当前进程实例的PID值

from multiprocessing import Process
import time
import os

def test(intervel):
    time.sleep(intervel)
    print("我是子进程")


def main():
    print('主进程开始')
    p = Process(target=test, args=(1,))
    p.start()
    print('主进程结束')






# 实例 使用Process子类创建2个进程,并记录子进程运行时间

def child_1(intervel):
    print('子进程(%s)开始执行,他的父进程是(%s)' %(os.getpid(), os.getppid()))
    t_start = time.time()
    time.sleep(intervel)
    t_end = time.time()
    print("子进程(%s)执行时间为%0.2f秒" %(os.getpid(), t_end - t_start))
def child_2(intervel):
    print('子进程(%s)开始执行,他的父进程是(%s)' %(os.getpid(), os.getppid()))
    t_start = time.time()
    time.sleep(intervel)
    t_end = time.time()
    print("子进程(%s)执行时间为%0.2f秒" %(os.getpid(), t_end - t_start))

def doubleMain():
    print('主进程开始')
    print('主进程PID:', os.getpid())
    p1 = Process(target=child_1, args=(1,))
    p2 = Process(target=child_2, name='mddn', args=(1,))
    p1.start()
    p2.start()
    print('p1 is_alive=%s', p1.is_alive())
    print('p2 is_alive=%s', p2.is_alive())
    print('p1.name=`%s`' % p1.name)
    print('p2.name=`%s`' % p2.name)
    p1.join()
    p2.join()
    print('主进程结束')


if __name__ == '__main__':
    # main()
    doubleMain()

        2. 使用Process子类创建进程

                run() 是进程运行时执行的方法

                start() 进程开始执行的方法

                调用start() 默认执行run()

from multiprocessing import Process
import time
import os

class SubProcess(Process):
    def __init__(self,interval,name=''):
        # 调用父类初始化方法
        # super(SubProcess,self).__init__()
        # 调用父类初始化方法
        Process.__init__(self)
        self.interval = interval
        if  name :
            self.name = name
    def run(self):
        print('子进程(%s)开始执行,他的父进程是(%s)' % (os.getpid(), os.getppid()))
        t_start = time.time()
        time.sleep(self.interval)
        t_end = time.time()
        print("子进程(%s)执行时间为%0.2f秒" % (os.getpid(), t_end - t_start))



def doubleMain():
    print('主进程开始')
    print('主进程PID:', os.getpid())
    p1 = SubProcess(interval=1,name='mddn')
    p2 = SubProcess(interval=2)
    p1.start()
    p2.start()
    print('p1 is_alive=%s', p1.is_alive())
    print('p2 is_alive=%s', p2.is_alive())
    print('p1.name=`%s`' % p1.name)
    print('p2.name=`%s`' % p2.name)
    p1.join()
    p2.join()
    print('主进程结束')

if __name__ == '__main__':
    doubleMain()

        3. 使用进程池Pool创建进程

                apply_async(func[, args[, kwds]]) 使用非阻塞方式调用func函数(并行执行,阻塞方式必须等待上一个进程退出才能执行下一个)

                        args: 传递给func的参数列表

                        kwds: 传递给func的关键字参数列表

                apply(func[, args[, kwds]]) 使用组设方式调用func函数

                close() 关闭Pool,使其不在接收新的任务

                terminate() 不干任务是否完成,立即终止

                join() 主进程阻塞,等待子进程的退出,必须在close()或者terminate()之后使用

from multiprocessing import Pool
import os
import time

def task(name):
    print('子进程(%s)执行任务%s'%(os.getpid(), name))
    time.sleep(1)

if __name__ == '__main__':
    print('父进程(%s)'%os.getpid())
    pool = Pool(3)
    for i in range(10):
        pool.apply_async(task,args=(i,))

    pool.close()
    pool.join()
    print('所有子进程结束')

        4. 队列

                两个子进程之间无法直接通信,可以使用队列和管道进行通信

from multiprocessing import Process
import time
import os

f_num = 100

def plus():
    print('子进程1开始')
    global f_num
    f_num += 50
    print('f_num=%d'%f_num)
    print('子进程1结束')

def minus():
    print('子进程2开始')
    global f_num
    f_num -= 50
    print('f_num=%d'%f_num)
    print('子进程2结束')

if __name__ == '__main__':
   print('主进程开始')
   p1 = Process(target=plus)
   p2 = Process(target=minus)
   p1.start()
   p2.start()
   p1.join()
   p2.join()
   print('主程序结束')

        5. 多进程队列的使用

                队列先入先出

                queue类: 处理队列

                put(item, [block[, timeout]]) 将item消息写入队列

                        block: 默认为True,如果队列为空,block为false,则立即抛出异常,block如果为True,需要设置timeout超时时间,超时时间单位为秒

                get(item, [block[, timeout]]) 获取队列中的一条消息,然后将其从队列中删除

                get_nowait() 相当于get(False)

                empty() 判断队列是否为空,空:true 非空:false

                full() 查看队列是否已满

                qsize() 返回当前队列包含的消息数量

from multiprocessing import Queue

if __name__ == '__main__':
    q = Queue(3)
    q.put('消息1')
    q.put('消息2')
    print('队列是否已满…%s' % q.full())
    q.put('消息3')
    print('队列是否已满…%s' % q.full())
    try:
        # q.put('消息4', True, 2)
        q.put_nowait('消息4')
    except:
        print('消息已满, 现在的消息数量%s' % q.qsize())

    if not q.empty():
        print('从队列中取消息')
        for i in range(q.qsize()):
            print(q.get_nowait())
    if not q.full():
        q.put('消息5')
        print(q.qsize())

        6. 使用队列在进程间通信

from multiprocessing import Process, Queue
import time

def writr_task(q):
    if not q.full():
        for i in range(5):
            message = '消息' + str(i)
            q.put(message)
            print('写入:%s' % message)

def read_task(q):
    time.sleep(1)
    while not q.empty():
        print('读取:%s' % q.get(True, 2))


if __name__ == '__main__':
    print('主进程开始')
    q = Queue()
    pw = Process(target=writr_task, args=(q,))
    pr = Process(target=read_task, args=(q,))
    pw.start()
    pr.start()
    pw.join()
    pr.join()
    print('主进程结束')
  • 线程

        操作系统能够进行运算调度的最小单位,它包含在进程之中,是进程实际运作单位

        线程的特点

                1. 进程是资源分配的最小单位,线程是最小的执行单位

                2. 一个进程可以有多个线程

                3. 现成共享进程资源

        在多线程开发中,全局变量是多个线程都共享的数据,为防止数据混乱,通常使用互斥锁。

        而局部变量等是各自线程的,是非共享的,不需要使用互斥锁

        1. 使用threading模块创建线程

                threading模块中的Thread类创建线程

                Thread([group[, target[, name[,args[, kwargs]]]]])

                        group: 参数未使用,始终为None

                        target: 表示当前线程启动时执行的可调用对象

                        name: 线程实例的别名

                        args: 表示传递给target函数的参数元组

                        kwargs: 表示传递给target函数的参数字典

        current_thread().name 获取当前线程的name值

import threading
import time

def thread():
    for i in range(3):
        time.sleep(1)
        print('thread name is %s' % threading.current_thread().name)

if __name__ == '__main__':
    print('主线程开始')
    threads = [threading.Thread(target=thread) for i in range(4)]
    for t in threads:
        t.start()

    for t in threads:
        t.join()

    print('主线程结束')

        2. 使用thread子类创建线程

                继承thread类

                重写run()

                如不赋值不需要创建init()

from threading import Thread
import time

class subThread(Thread):
    def run(self):
        for i in range(3):
            time.sleep(1)
            msg = '子线程' + self.name + '执行 i=' + str(i)
            print(msg)



if __name__ == '__main__':
    print('主线程开始')
    t1 = subThread()
    t2 = subThread()
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print('主线程结束')

        3. 互斥锁

                互斥锁:防止多个线程同时读取某一内存中的区域

                threading.Lock() 加锁

                线程之间可以进行通信

from threading import Thread
import time
import os

f_num = 100

def plus():
    print('子线程1开始')
    global f_num
    f_num += 50
    print('f_num=%d'%f_num)
    print('子线程1结束')

def minus():
    print('子线程2开始')
    global f_num
    f_num -= 50
    print('f_num=%d'%f_num)
    print('子线程2结束')

if __name__ == '__main__':
   print('主线程开始')
   t1 = Thread(target=plus)
   t2 = Thread(target=minus)
   t1.start()
   t2.start()
   t1.join()
   t2.join()
   print('主线程序结束')

        4. 使用互斥锁

                threading.Lock() 创建锁

                锁对象.acquire([blocking]) 锁定

                        blocking:bool值,成功锁定返回true,否则返回false

                锁对象.release() 释放锁,未锁定调用抛出异常

                注意死锁!!!!!

from threading import Lock, Thread
import time

n = 100
def task():
    global n
    mutex.acquire()
    time.sleep(1)
    n -= 1
    print('够买成功剩余%d' % n)
    mutex.release()

if __name__=='__main__':
    mutex = Lock()
    t_list = []
    for i in range(10):
        t = Thread(target=task)
        t_list.append(t)
        t.start()

    for t in t_list:
        t.join()

        5. 使用队列在线程间通信

                生产者 product 消费者 consumer 仓库 queue

from queue import Queue
from threading import Thread
import time
import random

class Producer(Thread):
    def __init__(self, name, queue):
        Thread.__init__(self,name=name)
        self.data =queue
    def run(self):
        for i in range(5):
            print('生产者%s将产品%d加入队列' % (threading.current_thread().name, i))
            self.data.put(i)
            time.sleep(random.random())
        print('生产者%s完成' % threading.current_thread().name)

class Consumer(Thread):
    def __init__(self, name, queue):
        Thread.__init__(self, name=name)
        self.data =queue
    def run(self):
        for i in range(5):
            val = self.data.get()
            print('消费者%s将产品%d取出' % (threading.current_thread().name, val))
            time.sleep(random.random())
        print('消费者%s完成' % threading.current_thread().name)


if __name__ == '__main__':
    print('主线程开始')
    queue = Queue()
    producer = Producer('Producer', queue)
    consumer = Consumer('Consumer', queue)
    producer.start()
    consumer.start()
    producer.join()
    consumer.join()
    print('主线程结束')
  • 进程和线程的区别

        1. 进程是系统进行资源分配和调度的一个独立单位,线程是进程的一个实体,是cpu调度和分派的基本单位

        2. 进程之间是相互独立的,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,但互不影响,而同一个进程的多个线程是内存共享的,所有变量都由所有线程共享
        3. 由于进程间是独立的,因此一个进程的崩溃不会影响到其他进程;而线程是包含在进程之内的,线程的崩溃就会引发进程的崩溃,继而导致同一个进程内的其他线程也崩溃

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值