
参考的视频课程如下:
你觉得自己这辈子都学不会编程?超超超基础Python课程,3小时快速入门 【自学Python教程合集】【3小时快速入门Python】
学习了一天粒粒老师的课程就通关了,讲解的非常简单易懂,有动画做辅助很适合小白
(资料图)
【B站最全最易学】北京大学终于将Python整理成了漫画书,漫画教学更生动,小白一学就会,拿走不谢,允许白嫖!!
比较系统的讲解了python的概念知识,作为一个补充来学习
建议刚学习的同学可以去第一个视频学习,然后再学习第二个视频会少很多问题
print("""笔记内容为本人学习的课堂笔记,结合自己搜索的例子,来解释课程不清楚的地方
都是非常非常基础的内容,适合刚接触这一块的小伙伴一起学习
有问题也欢迎在评论区一起讨论!""")
\ 转义符可以配合\' 或者 \"一起用 来强调引号是字符的属性
\n 指的是换行
"""_________""" 三引号 内容自动换行,下面长字符串那里有例子
\t 水平制表符
\n 换行符
\r 回车
\” 双引号 \’单引号 \\反斜杠
print("hel\\lo")
输出为:hel\lo
这个例子里,直接写成print(“he\llo”)是会报错的,需要加上\转义符
原始字符串
print(r"hel\\lo")
可以在最前方加上r来让print的结果与””引号内的内容一样
长字符串
使用三个”,或者”来讲内容括起来,会自动按照原始格式进行换行输出
比如:
print("""春风拂面,温暖如绸, 花开如海,香气袭人。 我走过绿茵的草地, 听着鸟儿歌唱的旋律。""")
输出为:
春风拂面,温暖如绸,
花开如海,香气袭人。
我走过绿茵的草地,
听着鸟儿歌唱的旋律。
字符串查找
a.find()函数可以用来查找字符串的索引值并且返回结果.
比如:
a ="春风拂面,温暖如绸,花开如海,香气袭人。" print(a.find("温"))
输出为: 5
还可以为搜索加上范围,比如:a.find(“温”,4,7),这样会在索引值为4和6之间进行搜索
或者用a.find(“温”,2) ,这样就是从索引值为2开始一直找到最后一个索引值
如果返回值为-1,就是没有找到需要搜索的字符串
字符串替换
可以用a.replace(“需替换”,”替换为”,数量) 数量为需要替换的个数,也可以不加,替换所有
比如:
a ="春风拂面,温暖如绸,花开如海,香气袭人。" print(a.replace(",","!",1))
输出为: 春风拂面!温暖如绸,花开如海,香气袭人。
--------------------
变量
名称中不能有空格,不能用数字开头,不能有除了_下划线以外的符号,不能用""引号包住,不能占用python关键字,比如print
变量名区分大小写,
a="变量名"
print(a+"xxxx")
储存变量
b=a
此时,可以给a赋予新的值
----------------------
运算
+-*/ **(平方)比如2 ** 3 表示2的3次方
import math
math.函数名(数值) --- math.sin(1)
-------------------------
#怕忘记了写这个
用#放最前面做注释
快捷键 ctrl+/ 选中代码行 可以多选
-------------------------
数值类型
数字≠字符串 不需要用""引号包住
字符串str 可以用Len函数得到字符串长度 len('hello')--->5 转义符\n只占一个长度 "HELLO"[3] 01234 返回值为L ,可以使用索引-1来表示最后一个元素 Print("HELLO[-1]") 就会输出O
整数int
浮点数float(带小数点的数字)
布尔类型bool 真和假 True False,注意开头需要大写
空值类型NoneType None 开头注意大写,不然不会识别,布尔也是开头需要大写
----------------------
python交互模式/命令行模式
在cmd用python进入
quit() 或者ctrl+d 退出
--------------
Input
输入的值会被视为字符串,如果直接参与运算会报错,
这里需要利用到int来将输入的数字转化为整数或者浮点数,比如age = int(input("你今年的年龄"))
-----------------------
条件语句
if True 或者False , 注意 if [条件]: 条件结束需要加上冒号: else可以省略
如if [条件]:
[执行语句]
[执行语句]
else:
[执行语句] 注意执行语句需要有缩进,来让系统判断此条语句是归if还是else来管
======
也可以用嵌套条件语句
比如
if [条件1]:
if[条件2]:
[执行语句]
else:
[执行语句]
======
elif语句,多个elif条件只会执行首个被满足的条件,后面的elif就不会被执行了
如下,
if [条件1]:
[执行语句1]
elif [条件2]:
[执行语句2]
elif [条件3]:
[执行语句3]
else:
[执行语句4]
比较运算符 == ,比如 3 ==3 --->True | "a" == "b" --->False
!= 不等于号,比如3 !=3 ---->False | "a" != "b" ---->True
此外还有 > ,>= , <,<=
逻辑运算
and or not
优先级not---->and---->or
可以用括号()改变运算顺序
not(x>5 and (x <10 or x ==12))
方法和函数
方法用法是:对象.方法名(...) 比如list.append("手套") ---->往list里面添加手套
同时可以用以下两种方法来追加多个元素,类似合并列表
a = ["a","b","c"] b = ["g","h","k"] b +=a b.extend(a) print(b)
函数的用法是:函数(对象) 比如len(list) ---------------->list的长度
python列表
list = ["1","2"] 中间用逗号隔开 这里列表中的数值类型可以是字符串,也可以是数字,如果是字符串的话需要加入引号"",数字则不用
列表是可变的,可以直接往里面添加新的元素
str,int,float,bool这类是不可变的,需要重新赋值才能变化
删除列表的某个元素:list.remove("手套"),注意remove的元素需要存在于列表中,不然会报错
列表可以存放不同类型的数据,比如str,float,bool,none
list[1] = "戒指" ---->可以用索引来对列表中的元素进行赋值
列表可以配合max,min,sorted函数来使用
比如print(max(list_num)) 表示打印列表中最大的数
print(min(list_num)) 表示打印列表中最小的数
print(sorted(list_num)) 表示打印排序后的列表,从小到大,注意sorted不适用于字符串
---------------------------------------------
集合
创建空集合的方式为set() 比如a = set() 而不用空的{},因为空的{}会默认创建空字典
或者用 b = {1,2,3,”abc”}创建 用大括号
集合不会包括重复的元素,会将重复的元素归一化,即使集合中有重复的元素,print时会自动去除重复的元素,集合中的元素是没有顺序的,
“”Item”” 是通常用作迭代过程中的变量名,表示集合(例如列表、元组、字典等)中的每个元素或键值对 ,可以替换成任意的名称
my_list = [1, 2, 3, 4, 5]
for item in my_list:
print(item)
集合可以用add或者remove方法来添加和移除元素
比如
num= {1,2,3,4} num.add(6) num.remove(1) print(num)
输出结果为: {2, 3, 4, 6}
也可以用clear()的方法来清空集合,使之变为空集合
例如:
num= {1,2,3,4} num.clear() print(num)
结果为: set()
两个集合是可以相互计算的,
交集 &或者intersection
并集 | 或者union
差集 - 或者difference
例如:
a = {1,2,3,4,"a"} b = {3,4,5,6,"a"} print(a&b) print(a.intersection(b))
{'a', 3, 4}
可以在集合中使用In和not in的测试运算符
num= {1,2,3,4} a = 1 in num print(a)
结果为: True
---------------------------------------------
字典
键:值 key:value
Name = dict()创建空字典
Name = {“a”:1}
可以用a =[键名]来获取值
比如:
a = {'agui': 123, 'xuge': 5565, 'sun': 777} b = a["agui"] print(b)
输出为: 123
也可以通过a[键名] = 新值 来更改值的值
a = {'agui': 123, 'xuge': 5565, 'sun': 777} a["agui"] = 321 print(a)
输出为: {'agui': 321, 'xuge': 5565, 'sun': 777}
可以用pop()函数来删除键值
比如:
a = {'agui': 123, 'xuge': 5565, 'sun': 777} a.pop("agui") print(a)
输出为: {'xuge': 5565, 'sun': 777}
比如 list = {"手套":"15元",}
键的类型必须是不可变的,列表是可变的,所以不能作为键来使用,str,int,float,bool等是可变的数据类型,可以作为键来使用
字典和列表一样都是可以改变的,比如需要往字典里添加元素
list = ["帽子"] = "85元"
如果需要print 字典 ,则需要将字典用str转化为字符串
如果需要删除字典的键值可以用
del list = ["帽子"] ,此时会删除键和相对应的值,如果键本身不存在的话就会报错
len函数同样适用于字典
如果只想要输出键的话可以用dict.keys() 方法
如果只想要输出值的话可以用dict.values() 方法
如果想要输出键和值的话可以用dict.items() 方法
举例:
keys_dict = dict(my_dict.keys())
print(keys_dict)
元组Tuple,
不可变,但是和列表很相似的数据结构,可以用作复杂的键来使用
比如 list = ("手套","帽子") 和列表的区别是,列表用的是[],元组的用的是(),由于是不可变的数据类型,所以append和remove都是不适用于元组的
当词典里"手套"的种类有若干时,可以用元组的方式来区分手套
list = {("手套","高"):"175元",
("手套","中"):"100元",
("手套","低"):"50元"}
创建元组的几种方式
可以用tuple()函数,或者1,来创建只有一个元素的元组 或者(1,3,4,5,6) 亦或者1,3,45,6
用a =()可以创建空的元组
a = tuple("hello") b = 1, c = (1,3,4,5) d = 1,2,34,5 e = () print(a) print(b) print(c) print(d) print(e) print(type(a)) print(type(b)) print(type(c)) print(type(d)) print(type(e))
('h', 'e', 'l', 'l', 'o')
(1,)
(1, 3, 4, 5)
(1, 2, 34, 5)
()
<class 'tuple'>
<class 'tuple'>
<class 'tuple'>
<class 'tuple'>
<class 'tuple'>
由于元组是不可变的,所以不能对元组进行修改、添加或删除元素的操作。如果需要修改元组中的元素,可以先将元组转换为列表进行修改,然后再转换回元组。
另外元组也可以用2个以上的元组来组成新的元组,比如
a = (1,2,3) b =(4,5,6) c= (7,8,9) d =(a,b,c) print(d)
结果为: ((1, 2, 3), (4, 5, 6), (7, 8, 9))
还可以用两个元组来组成字典,利用zip函数来实现
a = ("agui","xuge","sun") b = (123,5565,777) c = dict(zip(a,b)) print(c)
输出为: {'agui': 123, 'xuge': 5565, 'sun': 777}
通过元组的索引来创建字典,但是每次输出的结果不一样,键和值的顺序容易发生改变
a = ("agui",232) b = {a[0],a[1]} print(b)
输出为: {'agui', 232}
元组拆包
讲元组的元素拆包,并且赋值给变量id和name
id,name = (20152,"agui") print(id) print(name)
结果为:
20152
agui
---------------------------------------------------
for循环
迭代的对象可以是列表,字典,字符等,指的是按顺序对里面的元素做一些事情
基本结构为
for 变量名 in 可迭代对象
举例 在列表里列出大于5的数字
list = [1,2,3,4,8,9,0,-3,1.9,True,False]
for target in list:
if target > 5:
print(target)
输出为 8,9
举例,在词典里列出成绩不及格<60分的人
score = {"ming":55,"li":89,"su":99,"xu":42,"wang":32}
for mingzi,bujige in score.items():
if bujige<60:
print(mingzi,bujige)
输出为:
ming 55
xu 42
wang 32
range代表整数数列,range(1,10)代表1到9的数列 1代表起始值,10代表结束值,结束值不在数列范围里,所有只能表示1到9
举例
for i range(1,10):
print(i)
结果为1-9
for i range(1,10,2) 2为跳过的步长
print(i)
结果为1,3,5,7,9
-----------------------------------------------------------
while循环
基本结构为
while 条件A
行动B
举例:
list = ["我","喜","欢","喝","羊","肉","汤"]
while i <len(list):
print(list[i],end="")
i = i+1
输出为:我喜欢喝羊肉汤
如果不需要换行可以用end=""这个函数
输入数字来计算平均值,输入q结束并返回结果
i=input("请输入要计算的数字,输入q键来开始运算")
total = 0
times = 0
while i !="q":
total += int(i)
times += 1
i = input("请输入要计算的数字,输入q键来开始运算")
if times == 0:
avr = 0
else:
avr = total / times
print(int(avr))
这里需要注意if else和print的缩进,不要进入循环里,不然就会每次都打印出一次平均值了
--------------------------------------------------------------
格式化字符串
format
使用格式化字符串来将变量的值插入到字符串中。这可以通过在字符串中使用占位符 {} 来实现,并使用 .format() 方法将实际的值传递给这些占位符
也可以在print的开头打上f,来将变量的值
name = "agui"
year = "龙"
print("恭祝{0}新年快乐,在{1}年里事事顺心,{1}年大吉!!".format(name,year))
print("恭祝{n}新年快乐,在{y}年里事事顺心,{y}年大吉!!".format(n=name,y=year))
print(f"恭祝{name}新年快乐,在{year}年里事事顺心,{year}年大吉!!")
例子2
a = 1
b = 2
print(f"和为: {a + b}")
输出为:和为: 3
例子3
name = "agui" 这里需要用引号来定义name为str字符串
score = 21.22
print(f"{name}你好,你要查询的成绩为{score:.2f}") 这里注意score后面需要接: 不能直接用score.2f.
输出结果为:agui你好,你要查询的成绩为21.22
---------------------------------------------------------------
函数
定义函数 def()
举例
def agui():
name = "agui"
age = "29"
height = "165cm"
print("姓名:"+name + "\n"+ "年龄:"+age +"\n"+ "身高:"+height)
agui()
同时可以用def(a,b)来定义函数,没有明确的数值,但是每次调用的时候需要自定义a,b的数值
举例:
def agui(age,height):
name= "agui"
print("姓名:"+name + "\n"+ "年龄:"+age +"\n"+ "身高:"+height)
agui("18","165")
输出为:
姓名:agui
年龄:18
身高:165
自定义函数里面的值比如age,是没有办法被函数外直接调用的,
需要函数结尾加上reture语句,才能够被调用
例子:
def agui(age): name= "agui" return age
#---->这里添加return语句来返回age的值,让print里面的变量age能够正常运行 age=agui("18","165") print("agui的年龄为:"+age)
一般情况下,定义函数时的形参和使用函数时的实参需要保持位置一直,但是可以在实际参数里面加入形参的变量名称,就不会受到位置的限制了.比如上面的例子:
Age =agui(height=“165”,age=”18”)
也是可以正常使用函数的
函数的默认值
在定义函数的时候,可以给变量加上一个默认值,在这种情况下使用函数的时候,既可以使用函数默认的参数,也可以自定义参数
比如:
def agui(age="18"): return age age = agui() print("agui的年龄为:" + age) age = agui("20") print("agui的年龄为:" + age)
输出为:
agui的年龄为:18
agui的年龄为:20
可变参数
函数可以定义接受不确定数量的参数,被称为可变参数,有两种形式,
1在参数前加 *一个星号 在函数中被组装成一个元组
比如:
def scores(*scores): total_scores = 0 for score in scores: total_scores +=score return total_scores print(f"agui的总分为:{(scores(100,58,92))}")
输出为: agui的总分为:250
2 在参数前加** 两个星号
表示接收任意数量的关键字参数。它将这些关键字参数打包成一个字典(dictionary),可以在函数体内以字典的形式进行处理。这样,你可以传递任意数量的关键字参数给函数,并以键值对的形式进行传递。在函数内部,你可以通过字典的键来访问对应的值。
比如:
def scores(**scores): total_scores = 0 for course,score in scores.items(): total_scores += score print(f"{course}的成绩为:{score}") return total_scores print(f"agui的总分为: {scores(语文=100, 数学=58, 英语=92)}")
输出为:
语文的成绩为:100
数学的成绩为:58
英语的成绩为:92
agui的总分为: 250
总结:
*scores 接收任意数量的位置参数,并将它们打包成元组。
**scores 接收任意数量的关键字参数,并将它们打包成字典。
函数中变量的作用域
在模块中定义的变量为:全局变量
在函数中定义的变量为:局部变量
在函数中使用global()可以将局部变量变为全局变量,不然在函数外是无法调用变量的
比如:
def agui(): global age age = 18 print(f"局部变量为{age}") agui() print(f"全局变量为{age}")
输出为: 局部变量为18
全局变量为18
函数的类型
函数在python中的数据类型为function
在一个函数中也可以引入其他函数
比如:
def agui_wcn(age): print("agui今年未成年") def agui_cn(age): print("agui今年已经成年") def agui(year): if year < 18: #判断使用的函数 return agui_wcn else: return agui_cn years = int(input("请输入agui年龄")) wcn = agui(years) wcn(years)
当输入18时输出为: agui今年已经成年
过滤函数:
使用函数也可以对容器里的元素进行过滤,
基本格式为filter(函数,容器名)
比如:
def filter_func(a): return a <5 nums = [-1,-8,0,6,7,5,2,1] result =filter(filter_func,nums) #此时为filter数据类型,需要转换成list print(type(result)) #查看result的数据类型 result2 = list(result) #将filter类型转化为列表 print(result2)
输出为: <class 'filter'>
[-1, -8, 0, 2, 1]
也可以用for语句来遍历列表查找>5的数字,创建空列表,然后每次循环append符合的数字
list = list() #创建空列表 a = [-4,5,-8,0,6,8,4,2] for i in a: if i>=5: list.append(i) #将>5的数字添加到列表 print(list)
输出为: [5, 6, 8]
映射函数(map)使用方法类似过滤函数,是一个提供变换规则的函数,返回变换之后的元素
基本格式为map(函数,容器名):
比如:
def a(b): return b * 2 nums = [-1,0,3] result =map(a,nums) #使用映射函数 print(type(result)) #查看result的数据类型 result1= list(result) #将result转换为list print(result1)
输出为: <class 'map'>
[-2, 0, 6]
Lambda函数
Lambda定义的函数为匿名函数,也称为lambda函数
Lambda函数通常用于需要一个简单函数但不想使用完整函数定义的情况。它们可以作为参数传递给其他函数,或者用于在一行代码中定义简单的函数逻辑。
基本格式为:lambda 参数列表:lambda函数体
例子1:用于传递给其他函数
def agui(year): if year < 18: return lambda age:print("未成年") else: return lambda age:print("已成年") years = int(input("请输入agui年龄")) wcn = agui(years) wcn(years)
输入为15:输出为:未成年
例子2:定义简单的函数逻辑
add = lambda x,y:x+y result = add(2,5) print(result)
输出为:7
---------------------------------------------------------------
引入模块
import语句
举例:
import statistics
print(statistics.median([19,-5,36]))
from...import语句
form statistics import median
print(median([19,-5,36]))
from...import *
from statistics import *
这个语句是把模块里的所有内容都导入,使用时候都不需要加模块名
----------------------------------------------------------------
创建类class
一般类名的开头是大写的,并且不用下划线
基本格式为:
class 类名(父类) :
类体
父类也可以不加,如果加上父类就会继承父类的对象属性
可以用pass关键字来创建空类,相当于用来占位,保证代码的完整性,如果不加pass也没有类体的情况下就会报错.
如下
class Cat: pass
创建对象:
class Cat: def __init__(self): self.name = "Agui" cat = Cat() print(cat.name)
创建对象通常是通过实例化类来实现的,首先需要用class来创建类,
然后通过实例化对象
class Person: # 初始化方法 def __init__(self, name, age): self.name = name self.age = age # 创建方法 def greet(self): print(f"Hello, my name is {self.name} and I'm {self.age} years old.") # 创建对象的实例 person1 = Person("Alice", 25) person2 = Person("Bob", 30) # 访问对象的属性和方法 print(person1.name) # 输出: Alice print(person2.age) # 输出: 30 person1.greet() # 输出: Hello, my name is Alice and I'm 25 years old. person2.greet() # 输出: Hello, my name is Bob and I'm 30 years old.
在这个示例中
用 person1 = person(“Alice”,”25”)来创建对象示例
用 person1.greet() 来访问方法,当然也同样适用于访问对象 比如也可以访问person1.name这个属性
构造方法:
构造方法是一种特殊的方法,用于创建和初始化类的对象。构造方法在对象创建时自动调用,并负责执行一些必要的初始化操作,例如设置对象的初始状态、分配内存等。 在 Python 中,构造方法的名称固定为 __init__。它位于类的定义中,并以 self 作为第一个参数,用于引用正在创建的对象本身。除了 self 参数外,构造方法还可以接受其他参数,用于初始化对象的属性。
例子如下:
class Person: def __init__(self, name, age): #构造方法必须是__init__的名称 self.name = name self.age = age # 创建 Person 对象 person = Person("Alice", 25) #基于位置来传递参数 # 访问对象的属性 print(person.name) # 输出: Alice print(person.age) # 输出: 25
实例方法
实例方法是定义在类中的方法,用于操作和访问类的实例(对象)的数据。实例方法必须在类实例化后才能被调用,且在调用时会自动将实例本身作为第一个参数传递,通常被命名为 self。
比如:def talk(self): 此处定义方法的用法和定义函数相似,区别是:
一,需要写在class里,前面需要有缩进来表示这个方法属于该类,
二,第一个参数为self,用来表示对象自身
例子:
class human: def __init__(self,name): self.name = name def walk(self): print(f"{self.name} is walking.") def talk(self,sound): print(f"{self.name} says: {sound}") man = human("xiaoming") man.walk() #此处由于walk方法中没有其他参数,所以可以留空 man.talk(2) #这次由于talk方法中有sound参数,所以需要填写
输出为: xiaoming is walking.
xiaoming says: 2
类变量
类变量是属于类的变量,不属于单个对象.
比如:
class man: sex = "男性" def __init__(self,name,age): self.name = name self.age = age a = man("xiaoming",18) print(f"{a.name}是一个{a.age}岁的{a.sex}") #a.sex也可以写成Man.sex
输出为: xiaoming是一个18岁的男性
在这里性别就是类的变量,对象可以进行调用,
如果此时在print前面加上 a.sex = “女性”,那么会优先调用”女性”的这个值,如果想调用之前的变量值可以用类变量Man.sex来实现
类方法
在函数上行加入 @classmethod这个装饰器
比如
class Rate: rate = 0.6 #定义类变量 def __init__(self,price): self.price = price @classmethod #类方法装饰器 def a(cls,amount): #定义类方法 return cls.rate * amount #返回计算结果 c =Rate.a(500) #通过rate这个类来调用a这个类方法 print(c)
输出为:300
对于类方法的第一个参数,通常是cls,而不是之前的self
封装性
封装是面向对象编程中的一个重要概念,它指的是将数据和操作数据的方法包装在一个对象中,以实现数据的隐藏和保护。封装通过将数据设置为私有属性(private attribute)并提供公共接口(public interface)来实现。
封装的主要目的是隐藏对象内部的实现细节,使得对象的使用者只需要关注对象提供的公共接口,而不需要了解对象的具体实现细节。这样可以提高代码的可维护性、可扩展性和安全性。
举个例子:在用网线的时候,只需要将伸出来的线头插入设备,就可以正常的使用了,并不需要去了解网线内部结构.
私有变量
为了放置外部调用者随意存取类的内部结构(成员变量),内部数据(成员变量)会被封装为:私有变量
私有变量,在变量前加上双下划线 __
示例如下:
class Rate: __rate = 0.6 #定义类变量 def __init__(self,name,price): self.name = name #创建并初始化公有实例变量name self.__price = price #创建并初始化私有实例变量__price def prin(self): #公有方法用于访问私有变量 print(f"{self.name}的利率是{self.__rate},价格为:{self.__price}") a = Rate("手套",50) a.prin() print(f"商品名:{a.name}") #可以正常访问,输出结果为"手套" print(f"商品价格:{a.price}") #price为私有变量,所以无法访问会报错 print(f"商品利润率为:{a.__rate}") #rate为私有类变量,所有无法访问会报错
总结:私有变量是没办法被外部直接调用或者读取的,需要利用公有的方法来访问,
但是公有变量是可以直接用来访问的
如果直接在外部调用私有变量会造成AttributeError
私有方法
私有方法的封装是类似的,在方法名前加上双下划线__ 就会将公有方法变为私有方法
例子如下:
class Rate: __rate = 0.6 #定义类变量 def __init__(self,name,price): self.name = name #创建并初始化公有实例变量name self.__price = price #创建并初始化私有实例变量__price def __prin(self): #私有方法用于访问私有变量 print(f"{self.name}的利率是{self.__rate},价格为:{self.__price}") def get_prin(self): #创建公有方法用来访问私有方法__prin return self.__prin() a = Rate("手套",50) a.get_prin() #此处用get_prin的公有方法来访问私有方法__prin #如果直接写成a.prin()就会attributeError报错
输出为: 手套的利率是0.6,价格为:50
总结:私有方法和私有变量类似,也是无法直接进行外部访问的,需要借助其他的类方法进行访问和使用.如果直接调用的话,就会和私有变量一样,出现AttributeError的错误
使用属性(封装)
属性(property)是一种特殊的方法,它可以让我们使用类似于访问对象属性的语法来访问和修改对象的数据,同时可以在访问和修改时执行特定的逻辑。属性提供了一种更优雅和简洁的方式来控制对象的状态和行为。
在Python中,可以使用@property装饰器定义属性。属性由getter方法和可选的setter方法组成,分别用于获取和设置属性的值。getter方法使用@property装饰器修饰,setter方法使用@property装饰器的.setter装饰器修饰。
基本格式为:
@property (get装饰器)
def a(self):
return self.__a
@a.setter (set装饰器)
def a(self,a)
self.__a = a
下面用例子演示:
还是以手套为例
class Rate: def __init__(self,name,price): self.name = name self.__price = price @property #设置price的取值方法,即get def price(self): return self.__price @price.setter def price(self,price): self.__price = price a = Rate("手套",50) print(f"手套的价格为{a.price}") #这里是取值get a.price = 80 #a.price放在=的左边就是赋值set print(f"手套的新价格为:{a.price}") #由于重新被赋值,新的价格为80
输出为:
手套的价格为50
手套的新价格为:80
类的继承
继承性也是面向对象最重要的基本特征之一.在现实世界中继承关系无处不在
例如,猫与哺乳动物之间的关系,猫是哺乳动物,具有哺乳动物的特征,比如四条腿,两只眼,一个鼻子等,行为上比如走路,会尿尿等
此时可以将”哺乳动物”成为”猫”的父类.”猫”就是”哺乳动物”的子类,子类拥有父类的全部数据和行为,即数据和方法
子类的的调用属性,优先子类的方法,如果没有的话会调用父类同名的方法
如果给子类写了init方法,创建了子类实例时,会优先调用子类的构造函数,导致实例只有某种属性,
这是需要用到super(),用法是----> super().__init__(name,age)
class Mammal: def __init__(self,name): self.name = name def walk(self): return f"{self.name},今年{self.age}岁了,往前跑了两步" class Cat(Mammal): def __init__(self,name,age): super().__init__(name) #这里由于子类定义了age属性,要用super()来调用父类的参数信息 self.age = age cat1 = Cat("agui",2) print(cat1.walk())
输出为: agui,今年2岁了,往前跑了两步
比如walk的这个方法,子类中是没有的,但是由于Mammal是Cat的父类,所以方法也被继承到了子类中.
多继承
多继承是指一个类可以继承自多个父类的特性和行为。在Python中,多继承是一种面向对象编程的特性,允许一个类继承自多个父类,并继承它们的属性和方法。
比如class Cat3(Cat1,Cat2):
如果两个父类都有同样的实例变量,那么子类会优先继承第一个父类(Cat1)
如果父类拥有独特的成员变量,那么子类只继承拥有变量的父类的变量
举例如下:
class Cat1: def __init__(self,name): self.name =name def walk(self): return f"名字叫{self.name}的Cat1跑了起来" class Cat2: def __init__(self,name): self.name = name def walk(self): return f"名字叫{self.name}的Cat2跑了起来" def climb(self): return f"名字叫{self.name}的Cat2爬到了树上" class Cat3(Cat1,Cat2): def __init__(self,name): super().__init__(name) a = Cat3("agui") print(a.walk()) #由于Cat1和2都会walk,所以Cat3会继承Cat1的walk print(a.climb()) #由于只有Cat2会climb,所以Cat3会继承Cat2的climb
输出为:
名字叫agui的Cat1跑了起来
名字叫agui的Cat2爬到了树上
方法重写
如果子类中也定义了和父类同样的方法,那么会优先调用子类的方法
例子如下:
class Cat1: def __init__(self,name): self.name =name def walk(self): return f"名字叫{self.name}的Cat1跑了起来" class Cat2: def __init__(self,name): self.name = name def walk(self): return f"名字叫{self.name}的Cat2跑了起来" def climb(self): return f"名字叫{self.name}的Cat2爬到了树上" class Cat3(Cat1,Cat2): def __init__(self,name): super().__init__(name) def climb(self): return f"名字叫{self.name}的Cat3爬到了树上" a = Cat3("agui") print(a.climb())
由于父类Cat2和子类Cat3都拥有climb的方法,所有当子类Cat3继承父类Cat2时,会优先调用Cat3的climb方法
输出为: 名字叫agui的Cat3爬到了树上
多态性(重点)
“多态”指的是对象可以表现出多种形态
它允许不同类的对象对同一消息做出不同的响应。具体来说,多态性指的是通过使用父类的引用变量来调用子类的方法,根据实际对象的类型来确定调用的方法。这样可以实现代码的灵活性和可扩展性。
下面的例子通过定义了狗,猫和鸭子的sound,来实现不同动物的sound的区别
例子1:
class Animal: def sound(self): pass class Dog(Animal): def sound(self): print("汪汪汪") class Cat(Animal): def sound(self): print("喵喵喵") class Duck(Animal): def sound(self): print("嘎嘎嘎") animals =[Dog(),Cat(),Duck()] for animal in animals: animal.sound()
输出为: 汪汪汪
喵喵喵
嘎嘎嘎
例子2:
class Shape: def area(self): pass class Rectangle(Shape): def __init__(self, width, height): self.width = width self.height = height def area(self): return self.width * self.height class Circle(Shape): def __init__(self, radius): self.radius = radius def area(self): return 3.14 * self.radius * self.radius shapes = [Rectangle(4, 5), Circle(3), Rectangle(2, 7)] for shape in shapes: print("面积:", shape.area())
输出为:
面积: 20
面积: 28.259999999999998
面积: 14
总结:
多态一定是出现在继承的情况下,没有继承就没有多态
通过多态性,我们可以编写通用的代码,处理不同类型的对象,而不需要针对每个具体类编写特定的代码。这样可以提高代码的复用性和可维护性。
继承与多态
多态一定是出现在继承的情况下
在多个子类继承了父类,并且重写了父类的方法后,这些子类所创建的对象之间就是多态的,
比如上述的例子中,animals同时包含了狗,猫,鸭子,但是每种动物的叫声都是不同的,所采用的sound方式是不同的.
鸭子类型测试与多态
鸭子类型(Duck typing)是一种动态类型的概念,它关注的是对象的行为而不是类型本身。在鸭子类型中,一个对象的可用性不是基于它的类或继承关系,而是基于它是否具有特定的方法、属性或行为。
例子如下:
class Animal: def quack(self): print("有东西在叫!") class Duck(Animal): def quack(self): print("鸭子在嘎嘎叫") class Human(Animal): def quack(self): print("人在模仿鸭子嘎嘎叫") def check(obj): obj.quack() check(Duck()) check(Human())
输出为: 鸭子在嘎嘎叫
人在模仿鸭子嘎嘎叫”
在上面的例子中,定义了一个 Duck 类和一个 Human 类,它们都有相同的方法 quack。虽然他们的类别不同,但他们的行为类似于鸭子,因此可以通过鸭子类型的方式传递给函数 check,并调用相同的方法。
鸭子类型的核心思想是通过对象的行为来决定其可用性,而不是依赖于特定的类型或继承关系。这种灵活性使得代码更加通用和可复用,可以处理各种具有相似行为的对象,而无需显式地指定它们的类型。
异常(Exception)
异常(Exception)是在程序执行过程中出现的错误或异常情况。当发生异常时,程序会中断当前的执行流程,并跳转到异常处理代码块,以便进行错误处理、恢复或终止程序运行。
在Python中,异常是通过抛出(raise)和捕获(catch)来处理的。当发生异常时,可以使用try-except语句来捕获异常并进行相应的处理。try块中包含可能会引发异常的代码,而except块则包含异常处理的代码。
除零异常
当在数学计算时,分母为0时会出现的错误就是除零异常
例子:
i = input("请输出分母") n = 1 result = n/int(i) print(f"{n}除以{i}的结果为:{result}")
当输入为0时,报错ZeroDivisionError: division by zero
可以加入一个判断语句来避免此错误
i = input("请输出整数分母") n = 1 if i == "0": #判断输入的数字是否为0 print("请输入不为零的整数") #如果结果为零,则打印请输入不为零的整数 else: result = n/int(i) print(f"{n}除以{i}的结果为:{result}")
捕获异常
try-except语句的使用
基本格式为:
try:
<可能会引发异常的语句>
except异常类型 as 变量名:
<处理异常>
异常类型 as 变量名 都可以省略,省略时会捕获所有的异常类型并且不会储存变量
上面的例子可以改写成:
i = input("请输出分母") n = 1 try: result = n/int(i) print(f"{n}除以{i}的结果为:{result}") except ZeroDivisionError as b: print(f"不能除以0,出现了错误{b}")
当输入为0时输出: 不能除以0,出现了错误division by zero
多个except代码块
基本格式为:
try:
<可能会引发异常的语句>
except异常类型1 as 变量名:
<处理异常>
except异常类型2 as 变量名:
…
except:
<处理异常>
#省略异常类型的except代码块通常放在最后,来捕获没有匹配的异常类型,用来兜底
还是用刚才的例子:
i = input("请输出分母") n = 1 try: result = n/int(i) print(f"{n}除以{i}的结果为:{result}") except ZeroDivisionError as b: print(f"不能除以0,出现了错误{b}") except ValueError as b: print(f"输入的是无效数字,出现了错误{b}")
这里加入了另一个except代码来捕获输入字符类型的错误
当输入字母的时候,会输出: 输入的是无效数字,出现了错误invalid literal for int() with base 10: 'a'
多重异常捕获
也可以将except的异常类型放在小括号()中,并且用,逗号分割开
这样只需一个except代码就可以捕获多个异常了
例子:
i = input("请输出分母") n = 1 try: result = n/int(i) print(f"{n}除以{i}的结果为:{result}") except (ZeroDivisionError,ValueError) as b: print(f"输入的数字有误,出现了错误{b}")
此时,无论输入的是0还是非法字符,都会输出错误类型
try-except语句的嵌套
多重异常捕获和try-except语句块嵌套的区别在于异常处理的方式和代码结构的清晰度。
多重异常捕获是指在单个try-except语句块中捕获多个不同类型的异常。使用多个except子句来分别处理不同的异常类型。这样可以在单个try块中处理多个可能的异常情况,提高代码的简洁性。
try-except语句嵌套是指在一个try代码块中嵌套另一个try-except语句块。内层的try-except块可以用于处理更具体的异常情况,而外层的try-except块可以用于处理更一般的异常情况。这种嵌套结构可以提供更精细的异常处理逻辑。
例子:
i = input("请输出分母") n = 1 try: i = int(i) try: result = n / i print(f"{n}除以{i}的结果为:{result}") except ZeroDivisionError as b: print(f"输入的数字有误,出现了错误{b}") except ValueError as b: print(f"输入的是无效数字,出现了错误{b}")
finally代码块
有时在try-except语句中会占用一些系统资源,可以使用finally代码块来释放资源
例子:
i = input("请输出分母") n = 1 try: result = n/int(i) print(f"{n}除以{i}的结果为:{result}") except ZeroDivisionError as b: print(f"不能除以0,出现了错误{b}") except ValueError as b: print(f"输入的是无效数字,出现了错误{b}") finally: print("释放资源,无论是否出现异常,都是打印此段话")
在这个例子中,无论用户输入的是有效整数还是非整数,以及是否出现除零错误,最后的 print 语句都会被执行。finally 块通常用于清理资源、释放打开的文件、关闭数据库连接等必须执行的操作。
自定义异常类
class CustomException(Exception): def __init__(self,message): super().__init__(message)
手动引发异常
利用自己创建的异常类来使捕获的异常转化为自定义的异常
例子:
class CustomException(Exception): def __init__(self,message): super().__init__(message) i = input("请输出分母") n = 1 try: result = n/int(i) print(f"{n}除以{i}的结果为:{result}") except ZeroDivisionError as b: raise CustomException("不等除以0") except ValueError as b: raise CustomException("无效数字")
输出:raise CustomException("不等除以0")
__main__.CustomException: 不等除以0
----------------------------------------------
文件操作
读取文件
read 返回全部文件内容的字符串
例子:
f = open("./data.txt","r",encoding="utf-8") r为读 w为写 a为附加内容 encoding是编码
content = f.read()
print(content)
f.close() #最后运行close来释放内存
或者用
with open("./data.txt","r",encoding="utf-8") as f: #用with...as 这样的格式就不需要结尾用close关闭了,会自动关闭
content = f.read()
print(content)
readline 返回一行文件内容的字符串
例子:
with open("./data.txt","r",encoding="utf-8") as f:
print(f.readline())
注意缩进一定要有,不然会报错
readlines 返回全部文件内容组成的列表
例子:
with open("./data.txt","r",encoding="utf-8") as f:
lines = f.readlines()
for line in lines:
print(line)
readlines一般结合for循环使用,如果不想要换行符,可以用print(line.strip())来实现,就不会出现换行了
===============
写入文件
with open("./data.txt","w",encoding = "utf-8") as f: 如果文件不存在,会自动创建
insert插入
可以用
a.insert(2,”x”)来插入元素
比如:
a = ["a","b","c"] a.insert(2,"X") print(a)
” ['a', 'b', 'X', 'c']
替换元素
可以使用索引来替换掉相应位置的元素
a = ["a", "b", "c"] a[1] = "X" print(a)
['a', 'X', 'c']
杂项(不容易被分类的内容放到了这里)
来记录一些名词和概念,已经一些零散的使用方法
创建内容的方式
空集合set(), 或者a ={1,3,4,5}
空列表list() 或者 a = [1,2,3,4]
空元组tuple() 或者 a = (1,2,3,4)
空字典dict() 或者 a = {"a”:1,”b”:2}
在 Python 中,如果函数没有明确使用 return 语句返回一个值,或者只是使用 return 语句而没有跟随任何值,那么函数会默认返回 None。这就是为什么在你提供的例子中,如果去掉 return 语句,result 变量会显示 None。
让我们看一个简单的示例来说明这一点:
def my_function(): print("Hello") result = my_function() print(result)
输出为:
Hello
None
在上述示例中,函数 my_function 只包含了一个 print 语句,而没有使用 return 语句返回任何值。当调用 my_function() 时,会在控制台打印 "Hello",但由于没有返回值,变量 result 的值为 None。 因此,在你提供的例子中,如果去掉 return 语句,函数 add_numbers 将会默认返回 None,导致 result 的值为 None。 如果你希望函数返回一个特定的值,在函数内部使用 return 语句来显式指定返回值即可。如果不需要返回值,可以省略 return 语句或者只使用 return 关键字,不跟随任何值。
math模块的函数与说明
标签: