一、介绍
Python属于解释型语言:
- 框架:
①接口自动化Python+requests;
②Web自动化:Python+selenium;
③移动端自动化:(手机app)Python+appium;
1安装Python
2、Python环境(Python解释器环境)搭建: ①下载解释器安装包;②自定义安装,勾选添加环境变量:Add Python 3.10 to Path(目的是让程序可以在任意的目录下去执行);③cmd中输入python
查看信息。
官网:https://www.python.org/
Windows上输入:python,而macos上输入:python3。
mac终端中输入:echo 'alias python="python3"' >> .bash_profile
卸载Python:
2PyCharm环境搭建
3、pycharm环境搭建:(一般都是用的虚拟环境,而不是本地已存在的环境)
3PyCharm创建虚拟环境
PyCharm创建虚拟环境:https://miaojiang.blog.csdn.net/article/details/121493112
4基本设置
快捷键
修改字体大小:菜单栏 =》file ----> setting —> editor —>font —> size 修改为需要大小字号例如20,点击ok。
命令行运行python文件:
滚轮缩小字体:搜索decrease,Ctrl+鼠标滚轮向下,减小字体。
快速格式化代码:Ctrl+Alt+L(code =》 reformat code)
插件
汉化软件插件:搜索chinese安装插件(安装量最多的)
翻译软件:translation
模板
5.参考笔记
Python基础笔记:https://blog.csdn.net/overcomemyself/article/details/106679109
https://blog.csdn.net/overcomemyself/article/details/106682866
二、常见问题
无法初始化设备PRN
Debug
三、基础知识
命名
- 私有类用下划线开头命名:
_HelloWorld
注释
- 单行注释:#;
- 多行注释:三对双引号 或者 三对单引号。
- 三种不同的波浪线:
print函数
将数据输出到文件中:
fp=open('D:/python_code/base/text.txt','a+')
print('HelloWorld',file=fp)
fp.close()
a+
中的a代表以读写的方式打开文件,如果文件不存在,就创建。如果存在,就在文件里追加内容。需要写的内容存到文件中,必须加:file=
xx。- 不进行换行输出(输出的内容在一行当中):
print('Hello','World','Python')
转义字符
多行语句
数据类型
分类
type() 和instance
1、查看某个变量的数据类型:print(type(变量))
例如:num = ‘20’ print(type(num)) # <class ‘str’>
- 此外还可以用 isinstance 来判断:
>>> a = 111
>>> isinstance(a, int)
True
>>>
isinstance 和 type 的区别在于:
- type()不会认为子类是一种父类类型。
- isinstance()会认为子类是一种父类类型。
>>> class A:
... pass
...
>>> class B(A):
... pass
...
>>> isinstance(A(), A)
True
>>> type(A()) == A
True
>>> isinstance(B(), A)
True
>>> type(B()) == A
False
input
2、输入input:使用input获取到的内容,都是字符串类型,即str
数据类型转换
3、数据类型转换:不会改变原数据的类型。
交互式运行代码
4、交互运行代码:Python Console
格式化输出
普通格式化输出存在的问题:1.字符串拼接,导致代码可读性差;2.非字符串类型的数据,还要进行类型转换。
格式化输出-format方法实现:
转义字符:①换行,回车:\n
;②制表符,tab键:\t
;
为什么两个 print() 函数会换行输出呢? 因为 print() 函数默认自带 end='\n'
这个换行结束符。移除换行:print('内容', end='')
程序的输入:
num1 = int(input("请输入第一个数字:"))
num2 = int(input("请输入第二个数字:"))
print(f"{num1} + {num2} = {num1 + num2}")
运算符
①求商:// ,获取的是两个数据做除法的商。(被除数 ÷ 除数 = 商…余数)
②取余:%,获取的是两个数据做除法的余数。
③幂、次方:**
优先级: () > ** > * / // % > + -
④赋值运算法:
多个变量赋值
流程控制
If分支语句
1、if else结构。
2、if和逻辑运算符结合。
3、if elif else结构。
4、if嵌套。
5、综合应用(石头剪刀布):
import random
# 控制台出拳
player = int(input('请出拳 石头1/剪刀2/布3:'))
# 电脑随机出拳
computer = random.randint(1, 3)
# 1、玩家胜利
if(player == 1 and computer == 2) or (player == 2 and computer == 3) or (player == 3 and computer == 1):
print('玩家胜利')
# 2、平局
elif player == computer:
print('平局')
# 3、电脑胜利
else:
print('电脑胜利')
随机数:①import random ②random.randint(a, b) # 产⽣[a, b]之间的随机整数,包含a和 b
while&for循环
1、while循环。
2、死循环和无限循环。①break:终止循环;②结束本次循环,继续下一次循环。
3、for循环:称为for遍历,也可以做指定次数的循环。遍历:是从容器(字符串、列表、元组、字典)中将数据逐个取出的过程。
例如:①for循环遍历字符串:for 变量 in 字符串:
②for为指定次数的循环:for 变量 in range(n):
其中的range(n)可以生成[0,n)
的整数序列,不包含n
。n就是要循环的次数。
# for循环实现1~100的累加和
num = 0
for i in range(101):
num += i
print('求和的结果为:', num)
容器
切片操作适用于:字符串(str)/列表(list)/元组(tuple)
len():适用类型: 字符串、列表、元组、字典
1.字符串
Python 没有单独的字符类型,一个字符就是长度为 1 的字符串。
1、使用引号(单引号, 双引号, 三引号)引起来的内容,就是字符串。
2、原生字符串 在字符串的前边 加上 r""
, 字符串中的 \ 就不会进行转义。
3、下标(索引), 是数据在容器(字符串, 列表, 元组)中的位置, 编号。Python 中是支持负数下标, -1 表示最后一个位置的数据。
【注意】与 C 字符串不同的是,Python 字符串不能被改变
。向一个索引位置赋值,比如word[0] = 'm’会导致错误。
1-1.切片
4、切片:使用切片操作, 可以一次性获取容器中的多个数据(多个数据之间存在一定的规律,数据的下标是 等差数列(相邻的两个数字之间的差值是一样的))。语法:容器[start:end:step]
。
my_str = 'abcdefg'
# 需求1 : 打印字符串中 abc 字符 start 0, end 3, step 1
print(my_str[0:3:1]) # abc
# 1.1 如果步长是 1, 可以省略不写
print(my_str[0:3]) # abc
# 1.2 如果 start 开始位置的下标为 0, 可以不写,但是冒号不能少
print(my_str[:3]) # abc
# 需求 2: 打印字符串中的 efg , start 4, end 7, step 1
print(my_str[4: 7]) # efg
# 2.1 如果取到最后一个字符, end 可以不写,但是冒号不能少
print(my_str[4:]) # efg
# 需求 3: 打印字符串中的 aceg , start 0, end 7(最后), 步长 2
print(my_str[::2]) # aceg
# 练习: 打印cf
print(my_str[2:6:3])
# 特殊情况, 步长为 -1, 反转(逆序) 字符串
print(my_str[::-1]) # gfedcba
特殊情况, 步长为 -1
, 反转(逆序) 字符串:print(my_str[::-1]) # gfedcba
1-2.查找find()
1-3.替换replace()
字符串属于不可变数据类型,所有修改并不会影响原来的内容。
1-4.拆分split()
字符串.split(分隔符,分隔的次数)
①不传入分隔符时,默认按照空白字符分隔(空格,\n,\t)。
②分割次数不写,默认全部分割。
③得到的数据是列表list
。
1-5.连接 join
一般用于将列表按指定子字符合并为字符串:字符串.join(一般为列表)
,列表中的数据必须都是字符串才可以。
判断以什么结尾还可以用字符串.endswith()
:例如:’aaa’.endswith(‘a’)
2.列表list
2-1.定义
列表(list)是 Python 中使用最频繁的数据类型, 在其他语言中通常叫做数组, 专门用来存储一组数据。
1、列表,list, 使用 []。可以存放任意多个数据。可以存放任意类型
的数据。列表中数据之间 使用 逗号隔开。
2、列表支持下标和切片
3、求长度(数据的个数):len(列表)
2-2.查询-index()
2-3.查询-count()
列表.count(数据) # 统计 指定数据在列表中出现的次数。
list1 = ['hello', 2, 3, 2, 3, 4]
# 查找 2 出现的下标
num = list1.index(2)
print(num) # 1
# 统计数据 2 出现的次数
num1 = list1.count(2)
print(num1) # 2
# 统计数据 20 出现的次数
num2 = list1.count(20)
print(num2) # 0
2-4.添加数据 append()
方法执行是对原数据进行的修改
,固列表是可变数据类型
。
2-5.删除数据 pop()
列表.pop(下标),①如果书写的下标不存在,会报错。②返回:返回删除的数据。
①列表.pop(index) # 根据下标删除列表中的数据。index 下标可以不写, 默认删除最后一个。
②返回删除的数据
。
list1 = ['张三', '李四', '王五', '赵六']
# 删除最后一个数据
list1.pop()
print(list1) # ['张三', '李四', '王五']
# 删除第二个数据
name = list1.pop(1)
print('删除的对象为:', name) # 删除的对象为: 李四
print(list1) # ['张三', '王五']
2-6.修改数据
想要修改列表中的数据, 直接使用下标即可:列表[下标] = 新数据
。
2-7.列表的反转 reverse()
1、字符串的反转:字符串[::-1]
。
2、列表的反转:
①列表[::-1]
得到一个新的列表, 原列表不会改动。
②列表.reverse()
直接修改原列表的数据,返回None
。
my_list = ['a', 'b', 'c', 'd', 'e']
# 1. 切片的方法进行反转
my_list1 = my_list[::-1]
print('原列表my_list :', my_list) # 原列表my_list: ['a', 'b', 'c', 'd', 'e']
print('my_list1:', my_list1) # ['e', 'd', 'c', 'b', 'a']
# 2. reverse
my_list.reverse()
print('my_list :', my_list) # ['e', 'd', 'c', 'b', 'a']
2-8.列表的排序
(前提: 列表中的数据要一样)
①升序, 从小到大, 直接在原列表中进行排序:列表.sort()
②降序, 从大到下, 直接在原列表中进行排序:列表.sort(reverse=True)
my_list = [1, 4, 7, 2, 5, 8, 3, 6, 9]
# 升序
my_list.sort()
print(my_list)
# 降序
my_list.sort(reverse=True)
print(my_list)
2-9.列表的嵌套
列表的嵌套 就是指 列表中数据都是列表。
student_list = [["张三", "18", "功能测试"], ["李四", "20", "自动化测试"], ["王五", "21", "自动化测试"]]
# 打印所有人员的年龄
for info in student_list: # info 是 列表
print(info[1])
2-10.练习
判断以什么结尾还可以用字符串.endswith()
:例如:’aaa’.endswith(‘a’)
3.元组tuple
3-1.定义
①元组 tuple, 使用的是 ()
。
②元组和列表非常相似, 都可以存储多个数据, 都可以存储任意类型的数据
。
③区别就是元组中的数据不能修改
,列表中的数据可以修改
。
④ 因为元组中的数据不能修改,所以只能查询
, 如 len(), index(), count()
,支持下标和切片,可以访问指定位置的数据。
⑤元组主要用于传参和返回值。
【注意】:元组中只包含一个元素时,需要在元素后面添加逗号data = (1,)
3-2.组包和拆包
元组的特殊用法:交换两个变量的值
【面试题】
a = 10
b = 20
# c = b, a # 组包
# print(c) # (20, 10)
# a, b = c # 拆包 a(20) b(10)
# print(a, b) # 20 10
a, b = b, a
print(a, b) # 20 10
x, y, z = 'abc'
print(y) # b
4.字典dict
4-1.定义
【注意】字典中的键一般都使用字符串,并且键名不能重复
(如果重复原数据会被覆盖)。
4-2.增加和修改
【格式】:字典['键'] = 值
①键 存在, 修改;②键 不存在, 添加。
4-3.删除
字典的删除是根据字典的键 删除键值对。字典.pop('键')
。
4-4.查询
①字典['键']
# 键 不存在,会报错。
②字典.get(键)
# 键不存在,返回 None。
4-5.遍历
遍历字典的键:for key in 字典:
遍历字典的Key:for key in 字典.keys():
遍历字典的Value:for value in 字典.values():
遍历字典的Key和Value:for k, v in 字典.items():
1、遍历字典的键。
# 方式一
for 变量 in 字典:
print(变量)
# 方式二
for 变量 in 字典.keys(): # 字典.keys() 可以获取字典所有的键
print(变量)
2、遍历字典的值[使用较多]。
for 变量 in 字典.values(): # 字典.values() 可以获取字典中是所有的值
print(变量)
3、遍历字典的键和值。
# 变量1 就是 键, 变量2 就是值
for 变量1, 变量2 in 字典.items(): # 字典.items() 获取的是字典的键值对
print(变量1, 变量2)
5.集合
5-1.In操作符
1、数据 in 容器
可以⽤来判断 容器中是否包含这个数据。如果 包含返回 True,如果不包含返回 False。对于字典来说,判断的是字典中是否包含这个键。
5-2.集合 set(了解)
定义:{数据, 数据, …}
1、集合中的数据是不能重复的, 即没有重复数据。
2、对列表进⾏去重操作就是类型转换
, 可以将 列表转 换为 集合, 然后再将集合转换为列表。
my_list = [1, 2, 1, 2, 5, 2, 2, 4, 13]
# 方式一:使用set()方法进行去重。
list1 = list(set(my_list))
print(list1)
# 方式二:1.创建一个新列表。2.遍历原列表,使用in判断遍历出的元素是否在新列表中,
# 如果在就跳过,如果不在就添加到新列表中。
new_list = [] # 定义新列表 ,保存去重后的数据
# 遍历原列表
for i in my_list:
# 判断数据是否存在于新列表
if i not in new_list:
# 不存在, 添加到新列表
new_list.append(i)
print(new_list)
函数
Range函数的补充:
range(n) ---> [0, n)
range(start, end, step) ---> [start, end) 步长是 step,默认 1
range(1, 5, 2) # [1, 3]
range(1, 101) # 1-100
1.定义
type()
获取变量的数据类型。len()
获取容器的⻓度 (元素的个数)。range(n)
⽣成⼀个序列[0, n)。range(start, end, step) 表示 [start, end) 步长是step,默认为1
- 定义:
def 函数名():
。
2.文档注释
def get_max(x, y):
"""获取两个数中的最大值"""
if x > y:
return x
else:
return y
max_num = get_max(10, 20)
print(f"max_num={max_num}")
案例:
# 1. 定义名为 input_username 的函数, 获取用户输入的用户名
def input_username():
'''请输入用户名'''
return input('请输入用户名:')
# 2. 定义名为 input_password 的函数, 获取用户输入的密码
def input_password():
'''请输入密码'''
return input('请输入密码:')
# 3. 定义名为 login 的函数, 判断获取的用户名和密码信息
# 4. 要求当获取的用户名为:admin 并且密码为: 123456 时, 输出“登录成功!”,否则提示“用户名或密码错误!”
def login():
'''登录函数'''
if input_username() == 'admin' and input_password() == '123456':
print('登录成功')
else:
print('用户名或者密码错误')
login()
3.模块
如果模块的名字太长,可以使用 as 指定模块的名称,以方便在代码中的使用:import 模块名1 as 模块别名
【注意】:模块别名应该符合大驼峰命名法。
方式一:
import 模块名 # 模块名 就是代码⽂件名 ,不要 .py
# 使⽤其中的功能 模块名.功能名 (功能可以是变量, 函数 和类)
# 【多⽤于导⼊系统中的常⽤的模块和功能】
import random
num = random.randint(1, 10)
print(num)
方式二:
from 模块名 import 功能名 # 导⼊指定的功能
# 使⽤ 功能名()
# ⽅式⼆ 【多⽤于导⼊⾃⼰书写的,或者是第三⽅的模块】
# 【可以使⽤快捷键 Alt+回⻋】
from random import randint
num = randint(1, 10)
print(num)
练习:
4.__name__变量
【将不想执行的代码写在这个里面】
快捷写:直接写main然后回车即可。
【注意】一般情况下, 都需要将模块内的调试代码置于该条件下
, 以防止被其他模块导入后, 调试代码也参与执行。
def test01():
print("test01")
def test02():
"""函数嵌套调用:一个函数里面又调用了另外一个函数"""
print("test02")
test01()
if __name__ == '__main__':
test02()
5.模块导入顺序
1, 在导⼊模块的时候, 会先从代码所在的⽬录进⾏导⼊ 。
2, 如果没有找到,回去 Python 系统的⽬录查找导⼊ 。
3, 如果没有找到, 报错
【注意点】我们⾃⼰定义的代码⽂件名字 不要和你导⼊的系统的模 块⽂件名⼀样。
6.包
定义:将多个模块放在⼀个⽬录中集中管理(是一个包含多个模块的特殊目录), 并在这个⽬录中创建 ⼀个 __init__.py
⽂件(可以什么都不写), 就是⼀个包。
提示:在PyCharm中支持直接创建包,工程根目录上鼠标右键 =》 New =》 Python Package。
# ⽅式⼀
import 包名.模块名
# 使⽤:【包名.模块名.⼯具名】
# ⽅式⼆
from 包名 import 模块名
# 使⽤:【模块名.⼯具名】
# ⽅式三, 使⽤快捷键导包:【Alt+回车】
from 包名.模块名 import ⼯具名
# 直接使⽤⼯具名 (功能可以是变量, 函数 和类):【⼯具名】
综合案例:
- service包下的login_service.py
def login(username, password, code):
if code == "8888":
if username == "admin" and password == "hrj":
print('登录成功')
else:
print('用户名或者密码错误')
else:
print('验证码错误')
- script包下的test_login.py
from service.login_service import login
login('admin', 'hrj', '8888')
login('admin', 'href', '8888')
login('admin', 'hrj', '88888')
7.变量的进阶
7-1.引用
1、变量和数据是分开存储的;定义变量的时候,变量和数据都会在内存开辟空间。
2、数据 保存在内存中的一个位置;
3、变量 中保存着数据在内存中的地址;使用id() 函数
可以查看变量中保存数据所在的内存地址。
4、变量中记录数据的地址,就叫做引用
;Python中所有数据的传递,传递的都是引用(即地址)
5、【注意】当给一个变量重新赋值的时候,本质上是修改了数据的引用(赋值运算符(=), 会改变变量的引用, 即只有 = 可以修改变量的引用)。
①变量不再对之前的数据引用;
②变量改为对新复制的数据引用。
7-2.可变类型与不可变类型
7-3.局部变量和全局变量
【注意】在开发中, 大多不推荐使用全局变量, 可变范围太大, 会导致程序不好维护!
如果想要在函数外部使用局部变量的值, 使用 return 返回。
def func1():
list1.append(10)
def func2():
list1 = [1, 1] # 定义局部变量, 不影响全局变量
list1.append(0)
def func3():
global list1 # 全局变量
list1.pop() # 删除最后一个数据
def func_5():
list1.pop() # 用的全局变量,没有改引用
def func4():
global list1 # 全局变量
list1 = [1]
if __name__ == '__main__':
list1 = [1, 2]
func1()
print(list1) # ①[1, 2] ②[1, 2, 10](√) ③报错
func2()
print(list1) # ① [1, 1, 0] ②[1, 2, 10](√) ③报错
func3()
print(list1) # [1, 2]
# func_5()
# print(list1) # ②[1, 2] ①[1]对
func4()
print(list1) # [1]
8.函数的进阶
1、函数返回多个数据值:return a + b, a - b
,返回的是一个元组数据。
2、函数传参的方式:
def show_info(name, age):
print(f"name:{name}, age: {age}")
# 位置传参
show_info('小明', 18)
# 关键字传参
show_info(age=18, name='张三')
# 混合使用
show_info('李四', age=17) # 位置参数必须写在关键字参数的前边
8-1.缺省参数(默认参数)
1、在函数定义的时候, 给形参一个默认的数据值,这个参数就是缺省参数(默认参数)。
2、在函数调用的时候, 缺省参数可以不用传递实参值。
①如果不传实参值, 使用的就是默认值。
②如果传递实参值, 使用的就是传递的实参值。
【注意】缺省参数必须写在 普通参数的后边
。
def show_info(name, age=18, sex='保密'):
print(name, age, sex)
# 调用
show_info('张三', 18, '男')
show_info('李四') # 李四 18 保密
show_info('王五', 19) # 王五 19 保密
show_info('赵六', sex='男') # 赵六 18 男
8-2.多值参数(可变参数/不定长参数)
拆包
1, 在函数定义的时候,不确定在调用的时候,实参有多少个,此时可以使用 多值参数。
2, 在普通的参数前边加上一个 *
, 这个参数就变为:多值参数。
3, 这个参数可以接收任意多个位置传参的数据, 类型为元组
。
4, 这个形参一般写作 args(arguments), 即 *args
。
def 函数名(普通, *args, 缺省):
【函数调用过程中拆包】:
def my_sum(*args): # args 是元组
num = 0
for i in args:
num += i
return num
print(my_sum()) # 0
print(my_sum(1)) # 1
print(my_sum(1, 2)) # 3
print(my_sum(1, 2, 3)) # 6
my_tuple = (1, 2, 3, 4, 5)
# 需求对 元组中的所有数据使用 my_sum 进行求和
# 想要把列表(元组) 中的数据作为位置参数进行传递,
# 只需要在列表(元组)前边加上一个 * ,进行拆包即可
print(my_sum(*my_tuple)) # 15
8-3.匿名函数
匿名函数:使用 lambda
关键字定义的 表达式,称为匿名函数。
8-4.匿名函数的应用
要求按照年龄对用户数据进行排序。
9.函数练习
3.封装一个获取列表数据中最大值的函数:my_max()
- 也可以直接使用系统中找最大值的方法:
max(列表)
import random
def my_max(list1):
'''求列表中最大的值'''
max_num = list1[0]
for i in list1:
if i > max_num:
max_num = i
return max_num
if __name__ == '__main__':
my_list = []
for i in range(10):
my_list.append(random.randint(1, 100))
print(f"{my_list}中最大的数字为:{my_max(my_list)}")
5.