Python学习

一、python基础

1.变量及变量类型

概念
1.计算机的作用是计算,编程的目的为了更方便的计算,计算的对象是数据
2.变量是程序在运行过程中临时用于储存数据的东西
变量类型

  • 数组number
  • 布尔类型boolean
  • 列表 list
  • 元组 tuple
  • 字典 dict
    变量名命名规范
  • 变量名应简短而有意义
  • 单词使用小写字母,多个单词用下划线分割

2.标识符和关键字

标识符

标识符就是程序中用来标识变量,函数,类,或其他对象的名字

标识符命名规则

  • 只能包含字母、数字、下划线不能以数字开头
  • 区分大小写
  • 不能是python关键字
    在这里插入图片描述

3.输入和输出

# 常见的输出
print("我爱中国")

# 换行输出 \n 后的内容会在下一行打印
print("我爱\n中国")

# 拼接多个值
slogan = "我是纯爱战神"
print(slogan)
print("我的slogan是", slogan)

# 常见的获取键盘输入
# 可以使用input() 函数等待病获取用户键盘上的输入,用户回车结束输入,输入内容被认为
a = input()
password = input("请输入密码:")
print("用户密码为:", a)

# 关于函数
# 函数可以是别人或自己写的,可以直接使用,不用关心内部实现
# 函数有type(),print(),input()

first_number = input("请输入第一个数字:")
second_number = input("请输入第一个数字:")
result = int(first_number) + int(second_number)
print("计算结果为:", result)

'''
常用的类型转换
int() 转换为整数
float() 转换为浮点数
str() 转换为字符串
bool() 转换为布尔类型
'''

4.运算符

4.1算数运算符

在这里插入图片描述

注意混合运算时的优先级:** 高于 * / // % 高于 + -,最好的方法就是使用()处理优先级
不同类型数字运算时,整数会转换成浮点数进行运算

4.2 赋值运算符

在这里插入图片描述

4.3 关系运算符

在这里插入图片描述

4.4 逻辑运算符

在这里插入图片描述

5. 判断语句

'''
if else

if 条件:
    满足条件执行
else:
    不满足条件执行    
'''

# age = 17
age = 19
if age > 18:
    print("可以上网")
else:
    print("不能上网")

'''
if 条件1:
    事件1
elif 条件2:
    事件2
elif 条件3:
    事件3
else:
    事情4    
'''

score = 77
if 90 <= score <= 100:
    print("A")
elif 80 <= score < 90:
    print("B")
elif 70 <= score < 80:
    print("C")
else:
    print("D")


# if嵌套
a = "高"
b = "富"
c = "穷"
if a == "高":
    if b == "富":
        if c == "帅":
            print("高富帅")

# match...case...,python3.10以上版本的新特性,也属于分支结构的一种
x = 1
match x:
    case 1:
        print("x is 1")
    case 2:
        print("x is 2")
    case 3:
        print("x is 3")

6.循环语句

三大控制结构
顺序
分支
循环
用于控制代码的执行顺序

顺序:从上而下,顺序执行代码
分支:根据条件判断,确定执行哪个分支
循环:让特定代码块中的代码重复执行

6.1 while循环

基本语法

"""格式:
条件(满足时):
    执行内容
"""
while True:
    print("123")
# 上面代码缺少条件限制,导致死循环
i = 0
while i < 5:
	print("hello")
	i = i + 1

while 嵌套
和 if嵌套类似,while嵌套就是while里面还有while,审核或中华表盘上的时分秒针的运动就是循环嵌套的场景

  • 语法格式
'''
while 条件1:
        事件1
    while 条件2:
        事件2
'''

day = 1

while day <= 7:
    print("今天是第", day, "天")
    problem = 1
    while problem <= 3:
        print("做了", problem, "道题")
        problem += 1

    day += 1

6.2for循环

可以遍历任何可迭代对象,如:字符串,列表,元组,字典

  • 语法格式

for 临时变量 in 可迭代对象:
满足条件时执行的代码

6.3 break和continue

break

break作用是终止当前循环,并跳出循环体外,并继续执行循环之后的代码

i = 1
while i <= 5:
    print(i)
    if i == 3:
        break
    i += 1
continue

continue的作用是跳过本次循环中的剩余代码,直接进入下次循环

i = 1
while i <= 5:
    i += 1
    if i == 3:
        continue
    print(i)

注意点

  • break 和 continue 只能用在循环中,除此之外不能单独使用
  • break 和 continue在嵌套循环中,只能对最近的一层循环起作用
面试题
Python中如何跳出循环[2]
  • break,用于结束循环
  • continue,用于跳出本次循环,直接进入下一次循环

二、高级数据类型

1.字符串

双引号或单引号中的数据就是字符串

a = "abc"
b = "1234221"
############################
name = "张三"
age = 18
print("你好", name, ",祝你", age, "岁生日快乐!")
# 字符串格式化
#  就是把字符串嵌入到字符串中,推荐 字符串,format()
print("你好{},祝你{}岁生日快乐!".format(name, age))

# 自定义名片
name = input("请输入你的名字:")
position = input("请输入你的职位:")
company_name = input("请输入你的公司名字:")

print("-" * 30)
print("姓名:{}".format(name))
print("职位:")
print("公司名称")
print("-" * 30)

#  字符串下标
# 下标从0开始
# 下标从左往右,从0开始
s = "ABC"
print(s[0])

# 下标从右往左 从-1开始
print(s[-1])

# 字符串切片:截取其中一部分,字符串/元组/列表都支持切片
# 语法:[起始下标:结束下标:步长]
print(s[:])  # 取所有,默认步长为1
print(s[::2])  # 取所有,默认步长为2
print(s[:3])  # 取前三位
print(s[5:])  # 取第五位以后得内容
print(s[1:5])  # 取第2 3 4 5位的内容
print(s[1:5:2])  # 取第2 4位的内容
print(s[1:-1])  # 取第2到倒数第2位的内容
print(s[5:1:-1])  # 步长是负数,表示反向(从右往左),取第六位和第四位
# 字符串常见操作
# len(),可以获取字符串的长度
 s = "听君一些话,如同一席话"
 print(len(s))

# find() 和 index(),检测字符串中是否包含某个子串,如果包含某个子串
# 如果包含,则返回第一个找到的字串的初始下标
s = "听君一些话,如同一席话"
print(s.find(","))
print(s.index(","))
# 区别在于,如果找不到,find返回-1,index则抛出异常

# [了解] s.find(sub,start,end)
# star 表示搜索的起始位置,默认0[可选]
# star 表示搜索的结束始位置,默认字符串的长度[可选]
# index()也支持这种写法
print(s.find("一席话", 0, 11))

# replace()替换字符串中的某些子串,可以控制替换次数
print(s.replace("一", "二"))
print(s.replace("一", "二", 1))  # 替换一次

# count() 返回字符串中某个子串出现的次数
print(s.count("一席话"))
print(s.count("一席话", 6, 11))

# split() 以某字符为分隔符进行切片
print(s.split(","))
print(s.split("一"))

# startwith() 和endwith()检查字符串是否以某子串为开始或结束
print(s.startswith("听"))
print(s.endswith("话"))

# lower()和upper(),可以把字符串中的字符转为大写或小写
c = "Hello World"
print(c.lower())
print(c.upper())

# isalpha() isdigit() 和 isalnum(),判断字符串中所有字符都是 字母,数字,字母或者数字
s1 = "helloworld"
s2 = "123"
s3 = "helloworld123"
print(s1.isalpha())
print(s1.isdigit())
print(s1.isalnum())

# join(),格式为 分隔符.join(数据),数据可以是字符串,列表,字典,返回值是字符串
print("~".join(s))
l = ["广东省", "广州市", "天河区"]
print("".join(l))

面试题

1. 如何实现字符串的反转[2]

实现字符串反转的方法很多,比如切片,内置函数,循环等

  • 切片方式最为方便,只需要设置步长为-1即可
  • 内置函数的方法思路是先用reversed函数反转,在用join函数进行拼接
  • 循环的方法思路是遍历字符串的每个字符,循环拼接时,用新字符+就字符就可以
s = "听君一席话,如同一席话"
# 切片
print(s[::-1])

# 内置函数 reversed()返回逆序迭代器
print("".join(reversed(s)))

# 循环
print()
ss = ""  # 定义一个空字符串
for c in s:
    ss = c + ss  # 每次循环拿出的字符c,排在前面
print(ss)

2.列表

什么是列表

列表是python中使用非常频繁的数据类型,在其他语音中常叫作数据组
语法上用[]来定义一个列表,数据之间用逗号分隔

# 什么是列表
# 列表是python中使用非常频繁的数据类型,在其他语音中常叫作数据组
# 语法上用[]来定义一个列表,数据之间用逗号分隔,例如
name_list = ["张三", "李四", "王五"]
# 列表的索引从0开始(索引就是下标),引出超过索引范围会报错
# 列表可以储存不用类型的数据
l = ["张三", 100, [1, 2]]
print(l[0])

# 列表的遍历

# for

for name in name_list:
    print(name)

# while
i = 0
while i < len(name_list):
    print(name_list[i])
    i += 1

# 列表 常见地增删改查
# 增:append ,extend, insert
# append
l = [1, 2]
l.append(3)
l.append(True)
l.append([5, 6])
print(l)

# extend 可以把一个可迭代类型数据中的元素逐一加到列表中
a = [1, 2]
b = [3, 4]
c = "abc"
a.extend(b)
print(a)


# insert,可以在指定位置钱插入数据
l = [1, 2, 3, 4]
l.insert(2, "a")
print(l)

# print(l)
# 删:pop ,remove
# pop 根据索引删除列表中的数据,默认删除列表中的最后一个数据
l = [1, 2, 3, 4]
l.pop()
l.pop(2)
print(l)

# remove() 根据值从列表中删除数据
l = [1, 2, 3, 4]
l.remove(3)
ll = ["张三", "李四", "王五"]
ll.remove("李四")
print(l)


# 改,修改列表中数据有很多方法,需灵活使用,最常见的是根据下标进行数据的修改
l = [1, 2, 3, 4]
l[1] = 3
print(l)

# in和not in 用于判断列表中是否存在某条数据,成功为true,失败为false
if 1 in l:
    print("存在")
if 5 not in l:
    print("不存在")

# index 和 count
print(l.index(1))  # 返回下标
print(l.count(1)) #

# 排序 sort
# sort方法是可以将列表按顺序从新排列,默认为是从小到大,参数reverse = True是从大到小的

l = [1, 3, 4, 2]
l.sort()
print(l)
l.sort(reverse=True)
print(l)
# 注意:列表中的数据是同一类型时才可以排序,如果同时出现数字跟字符串则不能进行排序

# [了解] 列表生成式,帮我们生成列表
# 生成0-9的10个数
a = [x for x in range(10)]
print(a)

# 生成1-10
b = [x for x in range(1, 11)]
print(b)

# 生成10以内的奇数/偶数
c = [x for x in range(1, 11) if x % 2 == 1]
print(c)

d = [x for x in range(1, 11) if x % 2 == 0]
print(d)

面试题

列表中的数据如何拼接成字符串[1]
  • 想把列表中元素拼接成一个字符串有很多方法
  • 其一,我们可以使用join方法,用空字符串做分隔符来连接列表中的元素
  • 其二,我们可以使用+运算符,循环向空字符串中逐一添加列表中的元素
name_list1 = ["张三", "李四", "王五"]
# 1.使用+运算的方法
s = ""
name_list1 = ["张三", "李四", "王五"]
for name in name_list1:
    s += name
print(s)

# 2.使用join,用于将列表中的数据以某个分隔符进行连接,返回字符串
result = "".join(name_list1)
print(result)

3.元组

元组tuple 是与列表类似,语法上用()来定义一个元组

# 什么是元组
# 元组tuple 是与列表类似,语法上用()来定义一个元组
# 元组的常见操作,元组的数据不能修改
l = [1, 2, 3]
t = (1, 2, 3)
l[1] = 4
print(l)
# 对元组内的数据操作只支持查询类操作,如index,count
t = (1,2,3,4,5)
print(t.index(3))
print(t.count(4))

面试题

python中列表和元组的区别[2]
  • 列表是动态的,列表中数据支持增删改查的操作
  • 元组是静态的,元组中的数据只支持查询操作,可以理解为元组就是一个只读的列表
  • 从定义的角度说,列表需要中括号,元组用小括号来定义
  • 从设计的角度说,列表用于储存一系列动态变化的数据,如:坐标,日期等
  • 元组用于储存不变的数据,比如星期几
  • 从性能的角度来说,元组的性能优于列表(这和内存分配机制有关)
如果通过切片获取一个数据,倒数的三个元素[1]?
  • 首先很多数据类型都支持切片的操作,比如字符串,列表,元组
  • 切片的语法是用起始位,结束位和步长来控制
  • 如果想要回去倒数的三个元素只需要设置起始位为负三即可(形式为:变量名[-3,])

4.集合

集合 set 和列表,元组都很像

# 什么是集合
# 集合 set 和列表,元组都很像
# 区别:集合的用途保存不重复的数据
# 语法上:使用{} 或者set()
collection = {1, 2, 3, 4}
print(type(collection))

# [推荐] 使用set()函数创建集合,最只要的作用就是去重
l = [1, 2, 3, 3]
t = (1, 2, 3, 3)
c1 = set(l)
c2 = set(l)
print(c1, type(c1))
print(c2, type(c2))

# 集合也是可变的数据类型,可以有增删改查等各种操作

面试题

怎么实现列表去重?[2]

列表去重的实现方法有很多,比如可以利用集合类型的特性,也可以通过循环遍历的方式进行去重

  • 使用集合的特性去重
    • 先使用set函数把需要的去重的列表转换为集合类型,就完成了去重,但此时结果的集合类型
    • 如果西药列表类型,再使用list函数把数据类型转换回去即可
  • 使用循环遍历的方法去去重
    • 首先定义结果为一个空列表
    • 然后循环遍历原列表的元素,如果元素不存在空列表中,则通过append方法把元素添加进去
l = [1, 2, 3, 3]
# 使用集合去重
print(list(set(l)))
# 使用循环遍历的方式去重
res = []
for i in l:
    if i not in res:
        res.append(i)
print(res)

5.字典

什么是字典

字典 dict 语法上用{} 来定义字典,数据之间用","分隔
每个数据都是键值对的形式,包含,键名(key)和键值(value)两个部分

# 什么是字典
# 字典 dict  语法上用{} 来定义字典,数据之间用","分隔
# 每个数据都是键值对的形式,包含,键名(key)和键值(value)两个部分

d = {"":"","":""}
t_info = {"name":"小吨","sex":"男","年龄":18,"地址":"广州","hobby":["看电影","追剧"]}
# 在字典中找到数据不是根据下标来找的,是根据key
print(t_info["name"])
print(t_info["hobby"])

# 字典的常见操作
# 增加,使用 变量名["key"] = value 时,如果key在字典中不存在,就会新增这个数量
t_info["score"] = 10
print(t_info)

# 删除 pop 和clear 方法
t_info.pop("age")
print(t_info)
t_info.clear()
print(t_info)

# 改 和新增一样没使用变量名["key"] = value ,如果key在字典中存在,就会修改这个数据
t_info["age"] = 28
print(t_info)

# 查询 某个key对应的value
print(t_info["name"])  # 不存在时就会报错
print(t_info.get("name"))  #不存在时会返回空值



# 查询字典中的key列表,value列表,键值对的列表(以前返回列表,新版本python不再返回列表类型,但可以当做列表来使用后)
print(t_info.keys())
print(t_info.values())
print(t_info.items())

# 遍历
for key in t_info.keys():
    print(key)

for value in t_info.values():
    print(value)

for item in t_info.items():
    print(item)

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

面试题

1.python中有哪些数据类型,其中可变和不可变的数据类型有什么[3]
  • 常见的数据类型有整数 int,浮点型float,布尔bool,字符串string,列表list,元组tuple,集合set,字典dictionary
  • 其中可变类型有:列表,集合,字典
  • 不可变数据类型有:数字,布尔,字符串,元组
2.python中的字典怎么遍历[2]
  • 字典类型有很多内置方法可以使用,如:变量名.key() 获取键列表,变量名.values()获取值列表,变量名.items() 获取包含了键和值的元组的列表
  • 有了这些可迭代的列表数据,就可以通过for循环遍历了

6.小结

容器是可以存储多个元素的一种数据类型,在python中包括了字符串,列表,元组,集合,字典

# 容器
# 容器是可以存储多个元素的一种数据类型,在python中包括了字符串,列表,元组,集合,字典
# 解包: 指将容器中的元素,分别赋值给多个变量的过程(容器类型的数据都支持解包)

# 列表解包
a, b, c = [1, 2, 3]

# 元组解包
a, b, c = (1, 2, 3)

# 换位

a, b = b, a

# 操作容器的内置函数
s = "123"
l = [1, 2, 3]
t = (1, 2, 3)
c = {1, 2, 3}
d = {"a": 1, "b": 2, "c": 3}

# len(),可以计算容器中的元素个数
print(len(s))
print(len(l))
print(len(t))
print(len(d))

# max() ,min()分别返回容器中元素的最大值或最小值
max(max(s))  # 除了字典之外的类型,直接返回值
max(min(s))
max(max(d))  # 字典类型,返回的是值所对应的key
max(min(d))

# del 和垃圾回收机制有关,del可以删除变量(的引用,引用次数计数器为0时,垃圾回收机制自动释放内存)
# 有两种用法:
#     del + 空格
#     del()
# 对与不可变数据类型,是可以删变量,不能删除元素
del l[0]
del l
del d["a"]
del d
# 集合比较特殊,集合虽然可变,但无序,不能使用下边,这笔能删除变量
# 多维列表/元组的访问
l = [[1, 2], [3, 4]]
print(l[0])
print(l[0][0])
print(l[1][1])



三、函数

1.函数介绍

函数的含义:可以被重复使用的代码块

  • 函数的使用步骤:
    • 1.定义函数,封装独立的功能,
    • 定义函数的语法, def 是define的缩写

# 函数的含义:可以被重复使用的代码块
# 函数的使用步骤:
# 1.定义函数,封装独立的功能,
# 定义函数的语法, def 是define的缩写
# 定义过程,只定义,不执行
# def 函数():
#     代码
# 2.调用函数,使用封装好的功能
# 调用函数的语法,调用函数时会实际执行
# 函数名()
def fozu():
    print("我是佛祖")


fozu()

# 查看函数的使用文档,使用help()
print(help(len))

2.函数的参数

def add_2num():
    x = 1
    y = 2
    print(x + y)

add_2num()

# 这个函数只能把固定的两个数相加,怎样让这个函数适用于可变的两个数相加,答案就是参数
def add(x, y):
    print(x + y)


add(2, 3)

# 参数的基本含义
# 形参:在定义时使用,用于在调用时接收变量值的形式参数(如,上述代码中的x和y)
# 实参:在调用时传入的实际参数值(如,上述代码中的2和3)

# 注意,在调用函数时,参数的位置和数量要保持一致
def add(x, y):
    print(x + y)

# add(2, 3,2)  参数数量不一致会报错
# add(y = 1,x = 2) 如果位置需要变动,则需要以 变量名 = 参数值 的形式传参

# 参数的默认值(缺省值)

# 参数的默认值(缺省值),需要保证带有默认值的参数在末尾 def add(x=1,y)
def add(x, y=1):
    print(x + y)


add(2, 2)
add(1)

# 参数[拓展]
# def len(*args,**kwargs):在这个定义中*args和**kwargs是什么?
# 用于参数不确定的情况
# *args 用于接收不确定的个数的参数,它将传入的参数打包成一个元组
# **kwargs 用于接收不确定个数的关键字参数(键 = 值) ,并打包成一个字典

# 说明
# args和kwargs 是可改变名字的,但不推荐
# 参数定义是有顺序的:必选参数,默认参数,可变参数
def demo(a, b, c=1, *args, **kwargs):
    print(a)
    print(b)
    print(c)
    print(args)
    print(kwargs)

面试题

python的函数怎么传入可变参数或传参时的** *是什么意思[1]
  • 设计函数时,如果不确定参数的个数,这个时候我们就需要传入可变参数
  • *用于接收不确定格式的参数,并打包成一个元组,定义形参时通常用 *args
  • ** 用于接收不切定格式的关键词参数,并打包成一个字典,定义形参时通常用**kwargs

3.函数的返回值

# 什么是返回值
# 在程序开发中,有时候会希望一个函数执行结束后,
# 告诉调用者一个结果,这个结果就是返回值
# 在语法上,使用 return关键字来返回结果

def add(x, y):
    print(x + y)


a = add(1, 2)
print(a)  # 结果是none

def add(x, y):
    return x + y


print(add(1, 2))


def demo():
    print(1)
    print(2)
    return 0
    print(3)  #无法到达


print(demo())

4.函数的执行过程

# 函数中三大结构和嵌套调用的时候的执行过程
def demo1():
    print(1)
    print(2)
    print(3)


demo1()
print(100)
def demo2():
    print(1)
    if True:
        print(2)
    print(3)


demo2()
print(100)

def demo3():
    print(1)
    for i in range(3):
        print(2)
    print(3)


demo3()
print(100)

5.局部变量和全局变量

局部变量和全部变量

  • 从含义上说,局部变量定义在函数内部,全部变量定义在函数外部

  • 对于作用域的角度来说,局部变量只能在函数内部使用,函数执行之后,变量会被回收,不同函数会有同名的局部变量

    • 全局变量可以在全局使用(不论函数内外),但如果全局变量太多肯呢个导致不好维护
    • 局部变量是在函数内部定义的变量,只能在函数内部使用
  • 注意

    • 局部变量和全局变量是相对的概念,局部是函数内部,全局是文件全局
      未来会接触到更大的变量

6.匿名函数

匿名函数的定定义语法是lambda 参数:表达式
匿名函数中不能使用print 表达是就是返回值(无需写retur

四、面向对象编程OOP

1.基本理解

两种思想的区别

  • 面向过程:强调的是步骤和过程,每一步都是自己亲自去实现,用怎么做的思想来解决
  • 面向对象:找个对象,让对象来实现(专业的人干专业的时儿),用谁来做的思想来解决问题
    • 面向对象是基于面向过程的

面向对象编程的优点

  • 面向过程: 根据业务逻辑从上到下写代码(之前的函数式编程都是面向过程的)
  • 面向对象:减少了重复代码,高度封装,易扩展

2.类和对象

面向对象编程的两个非常重要的概念:类和对象

2.1 类和对象的关系


类时抽象的
对象
对象是一个具体的事情
类和对象的关系

总结

  • 类就是创建对象的模板,程序开发中,应现有类,再有对象
    一个类可以有多个对象

2.1代码演示

2.3 类的构成

是一群具有相同特征或者行为的事务的统称

  • 特征是属性
  • 行为是方法

如何体现对象和对象之间的区别?
通过属性和方法来体现同一个类的不太用对象的区别

类由3个部分构成

  • 类的名称:类名
  • 类的属性:拥有的特征(名词)
  • 类的方法:拥有的能力(动词)

注意
在程序开发过程中,只关注需求中涉及的属性和方法

2.4 类的设计

3.基础语法

3.1 定义类和创建对象

定义类
定义一个类,格式如下:

class 类名
	属性
	方法

定义一个类

class Hero:
    hp = 1000

    def info(self):
        print("我是一个英雄")

说明

  • 类名的命名规则按照"大驼峰命名法" 每个单词的首字母,单词和单词之间没有下划线

创建对象
创建对象的格式为:

对象名1 = 类()
对象名2 = 类()

如:创建Hero类的对象

class Hero:
    hp = 1000

    def info(self):
        print("我是一个英雄")


an_qi_la = Hero()
print(an_qi_la.hp)
print(an_qi_la.info())

3.2 类中的方法

魔术方法

有些特殊方法,在python 代码执行时可以自动调用,这些方法被称为魔术方法

  • 魔术方法名有两侧各有2个下划线
  • 常用的魔术方法有__init__,__str__,__del__
  • 软件测试人员最常用的是__init__方法,用来完成属性的初始化,他在创建对象时默认执行

class Hero:
    hp = 1000

    def __init__(self):
        self.name = None
        self.sex = None
        self.hp = 0
        self.attack = 0

    def info(self):
        print("英雄")


anqila = Hero()
chengyaojin = Hero()

print(anqila.name)
print(anqila.sex)
print(anqila.hp)
print(anqila.attack)

类属性和实例属性

class 类名:
	# 类属性,表示的是类的共性,如汽车,共性的内容有,轮子,座椅,有方向盘,有挡风玻璃
	类属性名 =1
	类属性名 =2
	#实例属性,表示的是对象(实例) 的个性,轮子数量,轮毂样式,座椅数量,是不是敞篷
	def __int__(self,参数1,参数2):
	self.实例属性名1 = 参数1
	self.实例属性名2 = 参数2
实例方法

特点

  • 实例方法是每个对象化独有的
  • 实例方法需要带self 参数
  • 主要用于处理实例属性,也可以访问其他实例方法

语法

def 实例方法名(self,参数):
	pass

调用
对象.实例方法名(参数)

类方法

特点

  • 类方法是针对类定义对的方法
  • 类方法需带cls参数
  • 主要用于处理类属性,也可以访问其他类方法

语法

@classmethod
def 类方法名(cls):
	pass

类方法需要用装饰器 @classmethod来标识,告诉python解释器这是一个类方法

调用
类名.类方法名()

静态方法

特点

  • 如果想在类中封装一个方法,既不需要访问**实例属性和类属性*,也不需要访问实例方法和类方法*
  • 这个时候,就可以把这个方法封装成一个静态方法

语法

@staticmethod
def 静态方法名():
	pass

静态方法需要用装饰器@staticmethod来标识,告诉python解释器这是一个静态方法
调用
类名.静态方法名()

小结
  • 实例方法方法内部需要访问self.属性名 的实例属性,也可以访问类名.属性的类属性
  • 类方法方法内部只需要访问类属性
  • 静态方法,方法内部不需要访问任何属性

4.面向对象三大特征

4.1封装

说明

  • 封装是面向对象编程的第一步,将属性和方法,封装到一个类中
  • 对封装的进阶理解就是属性的私有化

私有化

  • 属性和方法都可以私有化,不让外部直接访问,可以提高数据的安全性
  • 私有化方法,在属性或者方法名前面加双下划线__
  • 私有化,也可以考虑设置入口,供外部访问
    • 方法1:对私有化的属性设置get和set方法,想外部访问时,调用get和set 方法即可
    • 方法2:python内置了一些访问方法

4.2 继承

什么是继承
class A:
    money = 10

    def study(self):
        print("学习好")


class B(A):
    pass


print(A.money)
print(B.money)
b = B()
b.study()

说明:
在程序中,继承描述的是多个类之间的所属关系
继承就是子类拥有父类的所有属性和方法

继承的好处
相同的代码不需要重复编写

此时如果需要定义一个eat方法,只需要定义在父类中,则其他子类会继承这个方法

单继承

语法

class 子类名(父类名)
	pass

说明:子类只需要封装自己特有的属性和方法

如果子类从父类继承来的方法不好用,怎么办
解决方案就是重写

class A:
    money = 10

    def study(self):
        print("学习好")


class B(A):
    def study(self):
        print("学习更好")

a = A()
b = B()
a.study()
b.study()

class B(A):
    pass

print(B._A__money) #有办法能够访问父类中的私有属性或方法,但一样不大
多继承

现实中的多继承
孩子会继承父母的特性

程序中的多继承
子类可以拥有多个父类,并具有所有父类的属性和方法

语法

class 子类名(父类名1, 父类名2)
	pass

实例

class A:
    def eat(self):
        pass


class B:
    def sleep(self):
        pass


class C(A, B):
    pass


c = C()
c.eat()
c.sleep()

多继承使用时的注意事项
如果不同的父类存在同名的属性或方法时,子类在调用时,调用的是哪个父类中的队形属性和方法呢?

开发时,应尽量避免发生这种容易混淆的情况

4.3 多态

概念
多态就是不同对象调用同名方法,产生不同的执行结果

  • 继承重写父类方法为前提
class Animal:
    def speak(self):
        print("嚎叫")


class Dog(Animal):
    def speak(self):
        print("汪汪")


class Cat(Animal):
    def speak(self):
        print("喵喵")


animal = Animal()
dog = Dog()
cat = Cat()


def speak(x):
    x.speak()


speak(animal)
speak(dog)
speak(cat)

作用
可以增加代码的灵活度

五、文件操作

1.文件操作的基本介绍

文件的认知

  • 计算机的文件,本质上就是长期存储设备上的一段数据(长期存储设备包括光盘/u盘/硬盘,但不包括内存)
  • 在计算机中,文件是以二进制的方式存储在硬盘上的
    • 文本文件,本质上依然是二进制文件(字符编码),只不过是查看的时候进行了解码,让二进制重新转为自然语言

文件的基本操作

  • 基本操作包括的范围,打开文件/读写文件/关闭文件
  • 读写的理解
    • 读,将文件按内容读入内存,可以理解为查看文件内容
    • 写, 将内存中的内容写入文件,可以理解为增/删/改文件内容并保存
  • 打开文件open和关闭文件close
    • open(文件名,访问模式) 用于打开一个文件,返回这个文件按对象,访问模式如下
    • r 只读的方式打开(默认访问模式)
    • w 打开文件用于写入,会覆盖写入,如文件不存在则创建
    • a 打开文件用于写入,会追加写入,如文件不存在则创建
    • b 二进制模式,使用时结合其他模式,rb,wb,ab
  • 使用read(n) 方法可以从文件读取n个字符的数据

说明: 其实文件操作存在一个叫做文件指针的概念,类似光标,他标记操作

注意

  • 编码问题,如:文件内容包含汉字时,读文件时容易出现编码错误
  • 文件内容较多时,可以逐行读取
f = open("test.txt", "r", encoding="utf-8")
for readline in f.readlines():
    print(readline, end="")  # 以什么结尾
f.close()

# 如果总是忘记close 怎么办[拓展]
# with语句可以优雅的处理资源管理问题
with open("test.txt", "r", encoding="utf-8") as f:
    print(f.read())
# 其实`with open("test.txt", "r", encoding="utf-8") as f:`
# 相当于 `f = open("test.txt", "r", encoding="utf-8")` 加上f.close()

2.文件按的相关操作

  • 除了对文件的读写等之外,对文件还有重命名,删除文件以及对文件夹的操作
    • 这些功能都在python的OS模块中
    • 学习相关操作之前,需要先了解模块和包
  • 什么是模块 什么是包
    • 把功能相关的函数和类,放在一个独立的py文件中,就形成了一个模块
    • 把功能相关的模块整理放到一个独立的文件夹中,就形成了一个包
    • 一个模块就是一个py文件,一个包就是一个包含了 __init__.py 文件的文件
# 如何导入封装好的模块,包
# 从结构上认清我们要导入的内容
#  项目1
#     包1
#         模块1
#             类1,方法1,函数1,变量1
#         模块2
#     包2
#  使用import 来导入模块和模块中定义的类/方法/函数/变量
import math

print(math.pi)  # π
print(math.sqrt(2))  # 平方根函数

# 如果想直接使用模块中的成员,不想以模块,成员的方式来使用
# from math import pi,sqrt
from math import *

print(pi)
print(sqrt(4))

# 给导入的对象取一个别名
from math import pi as PI

print(PI)  # 此时只能通过别名使用

import time as t

t.sleep(3)

语法小结
import 模块名
from 模块名 import 成员名
from 包名.模块名 import 成员名

# os模块的文件相关操作
import os

# 文件重命名
os.rename("test.txt", "test1.txt")

# 删除文件
os.remove("test1.txt")

# 获取当前目录
print(os.getcwd())
# 删除目录
os.rmdir()

六、异常

概念

程序在运行时,如果python解释器遇到了一个错误,会停止程序的运行,并提示错误信息,这些错误信息就是异常

提示信息的动作就是抛出异常(也叫提示信息或报错)

  • 正常的认识异常
    • 异常并不可怕,软件是给用户群体使用的,所谓异常,是很普通的用户场景
# 捕获异常 - 处理异常
# 当我们不确定某些能不能执行成功时,可以使用以下语法来避免程序的停止运行

# try:
#     尝试执行的代码
# except:
#     出错的处理代码
try:
    open("111.txt")
except:
    print(1)
print(2)

# 如果希望展示异常的信息,如何处理
try:
    open("111.txt")
except FileNotFoundError as e:
    print(e)
    print(1)
print(2)

try:
    # 让用户输入密码
except 密码为空的错误类型 as e:
    print(e)
except 密码错误的异常类型 as e:
    print(e)
except BaseException as e:
    print(e)
else:
    # 没有异常才会执行的代码
finally:
    # 无论是否有异常,都会执行

# 实践
try:
    num = int(input("请输入一个整数:"))
    result = 8 / num
    print(result)
except ZeroDivisionError as e:
    print(e)
    print("0不能做除数")
except ValueError as e:
    print(e)
    print("需要输入整数")
except BaseException as e:
    print(e)
    print("未知错误")
else:
    print("正常执行")
finally:
    print("怎样都会走")

手动抛出异常

vx_list = ["张三", "李四", "王五", "情敌"]
for vx in vx_list:
    print(vx)
    if vx == "情敌":
        raise Exception("我很生气")
# 自定义异常类
class VeryAngryException(BaseException):
    pass


vx_list = ["张三", "李四", "王五", "情敌"]
for vx in vx_list:
    print(vx)
    if vx == "情敌":
        raise VeryAngryException("我很生气")

面试题

如何捕捉一个异常[1]

使用try…catch…语法来捕捉异常,如果后续有需要执行的代码可以放在finally代码块中

七、拓展

1.深拷贝和浅拷贝

python赋值原理

  • 变量并不直接存储翠香,而是存储对象的引用(即对象在内存中的地址)
# 将一个变量赋值给另一个变量时复制的是什么,二者实际上指向的是同一个对象
# 问题:这意味着如果修改对象的值,两者都会受到影响
# 为了避免变量之间共享地址带来的问题,就有了浅拷贝,需要复制对象的值
# 浅拷贝
import copy

# 对于不可变的数据类型
a = 1
b = copy.copy(a)
print("a", id(a))
print("b", id(b))
# 对于可变数据类型复制的是值
l1 = [1, 2, 3]
l2 = copy.copy(l1)
print(id(l2))
print(id(l1))
l1[0] = 4
print(l1)
print(l2)

# 对于较复杂的数据,可变数据类型在内外层表现不同

l3 = [1, [2, 3]]
l4 = copy.copy(l3)
l3[0] = 4
l3[1][0] = 3
print(l3)
print(l4)

# 浅拷贝对对于不可变的数据类型,复制"引用"
# 浅拷贝对于可变数据
# 可变数据类型在外层时,复制的是"值"
# 可变数据类型在外层时,复制的是"引用"

# 深拷贝
l3 = [1, [2, 3]]
l4 = copy.deepcopy(l3)
print(id(l3))
print(id(l4))
print(id(l3[1]))
print(id(l4[1]))

# 深拷贝对于不可变数据类型复制的是引用
# 对于可变的数据类型复制的都是值

面试题

浅拷贝和深拷贝的区别[3]
  • 浅拷贝和深拷贝的出现源于变量赋值只赋予变量对数据对象的引用,当多个和变量引用同一个数据时,数据一旦修改,这些变量都会受影响
  • 浅拷贝和深拷贝在实现上都用到了copy模块,浅拷贝用的copy()函数,浅拷贝用的是deepcopy()函数
  • 对与不可变类型的数据处理,浅拷贝和深拷贝都是一样的,都是复制对数据的"引用",病会不会开辟新的地址
  • 对与可变类型的处理
    • 浅拷贝的处理方式是,外层的数据复制"值", 内层的数据只复制引用
    • 深拷贝的处理方式是,不论内外层都开辟新的内存地址,把值复制过来

2.冒泡排序

什么是冒泡排序
冒泡排序是经典的排序算法之一

# 基本思路:从小到大排序,冒泡结果是大数冒上来
def bubble_sort(x):
    for i in range(1, len(x)):
        for j in range(len(x) - i):
            if x[j] > x[j + 1]:
                x[j], x[j + 1] = x[j + 1], x[j]
    return x
l = [12,3,23,54,1,2,4]
print("待排序:", l)
print("待排序:", bubble_sort(l))

面试题

用python如何实现冒泡排序[3]

冒泡排序的核心是两层嵌套循环来实现

  • 外层控制循环的论次,每一轮找出当前最符合的元素,并冒泡
  • 内存控制每个元素两两比较的次数,以及元素位置的交换
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值