EECS课程前期学习Python的笔记

***self.p=float(p)***,注意用float改变精度,防止精度损失

  • range函数
1
2
3
4
5
6
7
for _a in range(3):
print(_a)#0,1,2
for _b in range(1,5):
print(_b)#1,2,3,4
for _c in range(1,8,2):
print(_c)#1,3,5,7
#从start——start+step——stop-1
  • 字符串
QQ截图20220913150319 QQ截图20220913150504 QQ截图20220913151004
  • 列表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
lst=[1,2,3,4,5,6,7,8]
ls=list([451,254,387,445,545,5866,7,8])
print(lst.index(7,1,8))index() #函数用于从列表中找出某个值第一个匹配项的索引位置,7表示查找的元素,start=1,end=8-1
print(lst[0:5:2])
lst.append(789)#列表增加操作
print(lst)
lst.append(ls)#直接在列表后面加了一个列表(被当成一个元素)
#[1, 2, 3, 4, 5, 6, 7, 8, 789, [451, 254, 387, 445, 545, 5866, 7, 8]]
lst.extend(ls)#向列表末位一次添加多个元素
#[1, 2, 3, 4, 5, 6, 7, 8, 789, [451, 254, 387, 445, 545, 5866, 7, 8], 451, 254, 387, 445, 545, 5866, 7, 8]
lst.insert(1,80)#在索引1的位置插入80
#[1, 80, 2, 3, 4, 5, 6, 7, 8, 789, [451, 254, 387, 445, 545, 5866, 7, 8], 451, 254, 387, 445, 545, 5866, 7, 8]
lst[5:]=ls#切掉后面的(包括),将后面的替换掉
#[1, 80, 2, 3, 4, 451, 254, 387, 445, 545, 5866, 7, 8]
lst.remove(80)#移除元素,或者多个相同元素的第一个,找不到值会报错
#[1, 2, 3, 4, 451, 254, 387, 445, 545, 5866, 7, 8]
del lst[1]#删除索引为1的元素,找不到不会报错
lst.pop(1)#根据索引移除
#[1, 3, 4, 451, 254, 387, 445, 545, 5866, 7, 8]
lst.pop()#不指定索引,移除列表中最后一个元素
#[1, 3, 4, 451, 254, 387, 445, 545, 5866, 7]
new_lst=lst[1:5]#利用切片产生新的列表,类似于删除,两个列表指向不同的空间/列表,修改其中一个不对另一个产生影响
#列表的强制复制/copy
newlist=[:]#即可复制出两个列表
#[3, 4, 451, 254]
lst[1:5]=[]#空列表删除元素
#[1, 387, 445, 545, 5866, 7]
lst.clear()
#[]
del lst#直接删除列表
print(lst)
lst[0]='HelloWorld'#一次修改一个值
print(lst)
lst[1:2]=['new','world',1234,5668]#切片一次修改多个值
print(ls,id(ls),'排序前')
ls.sort()
print(ls,id(ls),'排序后')
ls.sort(reverse=True)#True表示降序
print(ls,id(ls),'排序后')
ls.sort(reverse=False)#False表示升序
print(ls,id(ls),'排序后')

lst2=sorted(ls,reverse=True)#使用内置函数对列表排序,并产生一个新的列表,原列表不发生任何改变
print(lst2)

c='1-23+(23*23)*sda'
origin_new = re.split(r"([(+ - * /])",c)#分割字符串
print(origin_new)
  • 可变

QQ截图20220920144152

  • 错误举例,

remove之后L1的元素个数变化,2的索引变成了0,但是迭代的e仍然为1(从0变过来),导致2没有被计算

QQ截图20220920152813

  • print输出函数
1
2
3
4
5
6
7
8
9
10
11
12
13
print('hello',6)
hello 6
print('hello'+6)
Traceback (most recent call last):
File "<pyshell#12>", line 1, in <module>
print('hello'+6)
TypeError: can only concatenate str (not "int") to str
print('hello'+'6')
hello6
print('hello'+'world')
helloworld
print('hello','world')
hello world

+用于连接字符串,不可用于连接数字和字符串,首尾直接相连,不自动添加空格

,里面默认分隔符,自带空格,无论混合输出还是字符串连接

  • 字典
  • copy

实例中 dict2 其实是 dict1 的引用(别名),所以输出结果都是一致的,dict3 父对象进行了深拷贝,不会随dict1 修改而修改,子对象是浅拷贝所以随 dict1 的修改而修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
dict1 = {'user':'runoob','num':[1,2,3]}

dict2 = dict1 # 浅拷贝: 引用对象
dict3 = dict1.copy() # 浅拷贝:深拷贝父对象(一级目录),子对象(二级目录)不拷贝,还是引用

# 修改 data 数据
dict1['user']='root'
dict1['num'].remove(1)

# 输出结果
print(dict1)
print(dict2)
print(dict3)

实例中 dict2 其实是 dict1 的引用(别名),所以输出结果都是一致的,dict3 父对象进行了深拷贝,不会随dict1 修改而修改,子对象是浅拷贝所以随 dict1 的修改而修改。
{'num': [2, 3], 'user': 'root'}
{'num': [2, 3], 'user': 'root'}
{'num': [2, 3], 'user': 'runoob'}
  • 键值对储存数据,逗号分隔,无序序列
1
scores={'zhangsan':100,'lisi':78}
  • 字典是根据key查找value所在的位置

  • 字典元素获取和添加

1
2
3
4
5
6
7
8
scores.get()#找不到时返回None
score[]#找不到时会报错
scores.get('a',99)#99是a找不到时提供的一个默认值
#添加
smart_girl["age"] = 35 #有则修改,无则添加
smart_girl.update(name = "tyson", age = 80)
smart_girl.update({"name": "da ye", "age" : 30, "address" : "beijing "})
smart_girl.update(age=50)
  • key的判断
1
2
3
4
5
print('l' in h)#in/not in判断
print('l' not in h)
scores.clear()#清空字典元素
scores['']=98#新增元素或者修改元素
del scores[]#删除元素
  • 字典视图
1
2
3
4
5
6
7
values=h.values()
key=h.keys()
items=h.items()

print(values,type(values),list(values))
print(key,type(key),list(key))
print(items,type(items))
  • 字典元素遍历
1
2
for item in h:#item用于遍历键,get用于取值
print(item,h[item],h.get(item))
  • 字典的特点
1
2
3
4
5
6
d={'name':'zhangsan','name':'lisi','name':'liu'}
print(d)#注意是大括号,Key不允许重复,values可以重复
#元素是无序的,只可以根据keys计算values,查找速度很快
#keys必须是不可变对象
#字典可以根据需要动态伸缩
#字典会浪费大量内存,是一种空间换时间的数据结构
  • 字典生成式
1
2
3
4
5
6
7
itemd=['a','b','c']
price=[185,98,78]
f={itemd.upper():price for itemd,price in zip(itemd,price)}
dic=dict(zip(keys,values))
print(f)
#upper()用于大写
#itemd:price和itemd,price对应一致即可f={a.upper():b for a,b in zip(itemd,price)}
QQ截图20220913001944
  • 总结
QQ截图20220913002400
  • 分支结构
QQ截图20220913141628

注:两个float相等的比较:

​ 1.直接 == 比较

​ 2.abs相减比较

​ 3.isclose函数比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> import math
>>> a = 5.0
>>> b = 4.99998
>>> math.isclose(a, b, rel_tol=1e-5)
True
>>> math.isclose(a, b, rel_tol=1e-6)
False
It is also possible to compare two values using absolute tolerance,
which must be a non-negative value:

>>> import math
>>> a = 5.0
>>> b = 4.99998
>>> math.isclose(a, b, abs_tol=0.00003)
True
>>> math.isclose(a, b, abs_tol=0.00001)
False
  • 循环结构
QQ截图20220913142802 QQ截图20220913145243

break会打破当前循环,并直接跳回上一级循环;continue跳过本次循环,并继续这级循环

1
2
3
4
5
6
7
8
9
10
11
12
b=1
while b<=3:
print('请输入密码')
i=input()
if i=='4567':
print('Right')
break
else:
print('ERROR')
b+=1
else:
print('三次密码输入错误')#没有遇到break,执行完循环之后就执行else中的内容
  • 穷举法

  • 近似思想

  • 二分查找

QQ截图20220913153957 QQ截图20220913154522 QQ截图20220913154939
  • 元组

内置数据结构之一,不可变序列:没有增删改操作,如元组、字符串

可变序列:可以对序列执行增删改操作,对象地址不发生改变,如字典、列表

字典大括号{},列表中括号[],元组小括号()

1
2
3
4
5
6
7
8
bsg=[12,23,432,32]
print(id(bsg))
bsg.append(432)
print(id(bsg))
j='hello'
print(id(j))
j=j+'world'
print(id(j))
  • 元组的创建
1
2
3
4
5
6
7
8
9
10
t=('a','d','wd')
print(t,type(t))
g=tuple(('a','d','dsa'))
print(g,type(g))
j='a','d','dsa'
print(j,type(j))
o=('98',)#只有一个元素时,注意末尾加一个逗号,否则也会被当成原本的类型
print(o,type(o))
i=()#空元组
print(i)
  • 为什么要设计成不可变序列

​ a.多任务环境下,同时操作对象时不需要加锁

​ b.程序中尽量使用不可变序列

注意:

​ a.若元组中对象本身是不可变对象,则不能再引用其他对象

​ b.若元组中的对象是可变对象,则可变对象的引用不允许改变,但是数据可以改变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
s=(1,2,[1,23])
print(s,type(s))
print(s[0],type(s[0]),id(s[0]))
print(s[1],type(s[1]),id(s[1]))
print(s[2],type(s[2]),id(s[2]))
print(id(2))#此处的2和上面的2id相同,相同数值的id可能相同(字符串也可以)
s[2].append(12)#列表可以改变,但是s[2]=100修改引用不允许
print(s[2],type(s[2]),id(s[2]))
>>
1 <class 'int'> 2564618256624
2 <class 'int'> 2564618256656
[1, 23] <class 'list'> 2564623172544
2564618256656
[1, 23, 12] <class 'list'> 2564623172544
  • 元组的遍历
1
2
3
4
5
6
7
hd=('hello','world',98)
for _ in hd:
print(_)
#等效于一下代码
print(hd[0])
print(hd[1])
print(hd[2])

QQ截图20220920144858

  • 作用

QQ截图20220920145136

  • 集合

可变类型序列,是没有value的字典{key:value}

  • 集合的创建方式
1
2
3
4
5
6
7
8
9
10
11
12
s={'d',789,'sddsa',789,789}#集合不允许重复,且是无序存储
print(s,type(s),id(s))
s=set(range(0,9,2))#使用函数set转换成集合
print(s,type(s),id(s))
s=set([1,1,1,1,2,2,3])
print(s,type(s),id(s))
s=set((1,23,34,543))
#{1, 34, 543, 23} <class 'set'> 2104296556800
s=set('hello')#相同元素被删除
#{'h', 'l', 'e', 'o'} <class 'set'> 2104293205024
s=set()#空集合定义方法
print(s,type(s),id(s))#set() <class 'set'> 2104296556800
  • 集合相关操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
s={12,23,432,234,34}
'''集合元素的判断'''
print(12 in s,122 not in s)#True True
'''集合元素的新增'''
s.add(98)#一次添加一个元素
print(s)
s.update({233,987,546})#一次添加多个元素
s.update([1,2,3,4,5])
s.update((10,0,900))
print(s)
'''集合元素的删除'''
s.remove(1)#一次删除一个元素,元素不存在时会报异常
s.discard(800)#一次删除一个元素,元素不存在不报异常
s.pop()#一次删除任意一个元素,不可以指定
s.clear()#清空集合
print(s)
  • 集合间的关系
1
2
3
4
5
6
7
8
9
10
11
12
s1={1,2,3,4,5}
s2={2,3,4,5}
#集合相等可以用==和!=判断
print(s1 == s2,s1 != s2)
#s2是s1的子集
print(s2.issubset(s1),s1.issubset(s2))
#s1是s2的超集
print(s1.issuperset(s2),s2.issuperset(s1))
#两个集合是否含有交集
print(s1.isdisjoint(s2))#有交集为False
s3={3423}
print(s1.isdisjoint(s3))#没有交集为True
  • 集合的数据操作
1
2
3
4
5
6
7
8
9
10
#交集
print(s1.intersection(s2))
#并集
print(s1|s2)
print(s1.union(s2))
#差集
print(s1.difference(s2))
#对称差集:两个集合的并集减去交集
print(s1.symmetric_difference(s2))
#以上运算都不改变s1和s2的值
  • 集合生成式
1
2
3
4
5
6
#列表生成式
lst=[i*i for i in range(6)]
print(lst)
#集合生成式
lst={i*i for i in range(6)}
print(lst)
  • 列表、字典、元组、集合
数据结构 是否可变 是否重复 是否有序 定义符号
list 可变 可重复 有序 []
tuple 不可变 可重复 有序 ()
dict 可变 key不可重复/value可重复 无序 {key:value}
set 可变 不可重复 无序 {}
  • 函数

函数会额外创建一个空间用于储存内部的数据,被调用时在其中创建一个新的空间给变量,优先使用内部变量(局部变量)

  • 函数的创建

注意写完后进行输入输出注释,方便他人使用黑盒子

注意函数名和变量名不可以相同,否则程序可能无法分辨而出错

1
2
3
def 函数名([输入参数],[参数],[参数]):#其中输入参数为形式参数
函数体
[return xxx]
QQ截图20220920141253
  • 函数调用
1
2
3
4
5
6
7
8
9
10
函数名([实际参数])
def cal(a,b):
xxxx
return c
#位置传递
cal(1,2)#a=1,b=2
#关键字对应传递
cal(b=1,a=2)#a=2,b=1
'''不可变对象在函数体内的修改不会影响实参的值,如对数值的重新赋值
可变对象在函数体内的修改会影响到实参的值,如列表的append操作'''
  • 函数的返回值
1
2
3
4
5
6
7
8
9
10
11
12
13
'''
return 后可以是表达式也可以是数值
如果函数没有返回值,return可以省略
函数的返回值如果是一个,直接返回原值
函数的返回值如果是多个,返回的结果为元组
'''
'''
也可以输入和返回函数jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
如z()
def fun(a):
return a()
fun(z)
'''
  • 默认值参数
1
2
3
4
5
6
7
8
9
10
'''如果没有给b传值,则b默认为10,否则其为传递的值'''
def cal(a,b=10):
if a>=b:
return a
else:
return b
c=12
d=231
cal(a=92,98)#可以关键字参数和位置形参并用
print(cal(c))
  • 函数的参数定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
'''个数可变的位置参数:用*定义可变的位置形参
事先无法确定传递的位置实参的个数,结果为一个元组
'''
def fun(*args):
print(args)
fun(12,32,43,12)

'''个数可变的关键字参数
结果为一个字典,字符串前不需要加引号
'''
def h(**args):
print(args)
h(a=1,b=2,c=3,bsgbsg7=1)
#注:无论是哪种,都只能有一个可变的位置参数或者关键字参数,但在一个函数中可以同时使用两者,要求位置形参在关键字形参之前
def l(*args,**arg1):
pass
  • 变量的作用域

  • 局部变量

函数体内定义的变量

  • 全局变量

函数体外定义的变量

1
2
3
4
5
def fun3():
global age#使用global声明将局部变量提升为全局变量
age=19
fun3()#注意要先调用函数才能输出,函数都没调用哪来的age
print(age)
  • 例1中函数重新定义了x=1在自己开辟的内存中,改变x的值为改变局部变量的值,未改变外部x的值,仍为5;例2只访问了x的数值,未进行改变,也未在自己的函数空间内生成x局部变量;例3,函数内部未定义x,但是尝试改变全局变量会报错(只可以访问,不可以改变)QQ截图20220920143156

  • 面向对象

面向对象:事物比较复杂,使用简单的线性思维无法解决

面向过程:事物比较简单,可以使用线性思维去解决

  • 类与对象

类:数据类型

对象:包含数据(变量,称为特征)和代码(函数,称为方法)的自定义数据结构

  • 类的创建
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Student:#student为类名,首字母大写
place='吉林'#直接写在类里面的对象,称为类属性,该类被所有对象所共享

def __init__(self,name,age):#初始化
self.name=name#self.name称为实体属性,进行了一个赋值的操作,将局部变量name的值赋给实体属性
self.age=age

#实例方法(在类之外定义的称为函数,类之内定义的称为方法)
def eat(self):#必须要有self,实例方法传的是实例对象self
print('xuexi')

#静态方法
@staticmethod
def method():#不允许写self
print('staticmethod')

#类方法
@classmethod
def cm(cls):#class
print('class')

#Student为一个类对象,开了内存空间,有数值和类型
print(id(Student),type(Student),Student)
  • 对象的创建(类的实例化)
1
2
3
4
5
6
7
8
#Student为类对象,stu1为实例对象
stu1=Student('zhangsan ',18)
print(stu1,id(stu1),type(stu1))#stu1的值表示其内存地址
stu1.eat()
print(stu1.name,stu1.age,stu1.place)#调用输出

Student.eat(stu1) #stu1.eat()相同,都是调用Student中的eat方
#stu1对应self,要求传入类的对象;类名.方法名(类的对象)——实际就是方法定义处的self
  • 类属性,类方法,静态方法的使用方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#类属性的使用方式
stu1=Student('d',123)
stu2=Student('sd',12)
print(stu1.place,stu2.place)
Student.place='湖北'
print(stu1.place,stu2.place)
'''
类的实例对象都包含一个类指针,指向类对象,修改类对象也会影响类的实例对象
吉林 吉林
湖北 湖北
'''

#类方法的使用方式
Student.cm()#调用时不需要传入cls默认参数
#静态方法的使用方式
Student.method()
  • 绑定添加属性和方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class St:
def __init__(self,name,age):#初始化中的属性是所有实例对象都有的属性
self.name=name
self.age=age
def eat(self):#实例方法
print('eat')

stu3=St('bsg',12)
stu4=St('jsh',83)
stu3.gender='male' #为stu3绑定添加属性
print(stu3.name,stu3.age, stu3.gender)
print(stu4.name,stu4.age)
stu3.eat()
stu4.eat()
#动态绑定方法
def show():
print('定义在类之外的称为函数')
stu3.show=show #为stu3绑定添加方法
stu3.show()

QQ截图20220920202855

  • 总结

编程思想:

​ 面向对象

​ 面向过程

类对象(class):

​ 类属性

​ 类方法

​ 静态方法

​ 实例方法

(可以类名传入对象调用Student.eat(stu1),也可以对象名.调用stu1.eat())

实例对象:

​ 类名()创建实例对象

​ 动态绑定属性

​ 动态绑定方法

  • 面向对象的三大特征

    封装:将属性和方法包装到类对象中;如果不希望该属性在类对象的外部被访问,前边使用两个’_’

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    m=seFast.StateEstimator(cellSSM)
    print '123',m
    m.start()
    print '123',m


    ###seFast.StateEstimator(cellSSM)仍然是一个class,即使传了参数cellSSM也不是一个实例,上面的地址前后一致,下方的地址前后不一致

    print seFast.StateEstimator(cellSSM)
    seFast.StateEstimator(cellSSM).start()
    print seFast.StateEstimator(cellSSM).start()
    print seFast.StateEstimator(cellSSM)
    return seFast.StateEstimator(cellSSM)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Student:
    def __init__(self,name,age):
    self.name=name
    self.__age=age
    def show(self):
    print(self.name,self.__age)

    stu1=Student('bsgbsg7',19)
    print(dir(stu1))
    #print(stu1.name,stu1.__age)
    print(stu1._Student__age)
    stu1.show():

    继承:

    1
    2
    3
    4
    5
    6
    class 子类类名(父类1,父类2...):
    pass
    '''
    如果一个类没有继承任何类,则默认继承object
    定义子类时,必须在其构造函数中调用父类的构造函数
    '''
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    class Student:
    def __init__(self,name,age):
    self.name=name
    self.__age=age
    def show(self):
    print(self.name,self.__age)

    stu1=Student('bsgbsg7',19)
    print(dir(stu1))#dir用于查看所有属性和方法
    #print(stu1.name,stu1.__age)
    print(stu1._Student__age)
    stu1.show()

    class Pro(object):
    def __init__(self,name,age):
    self.name=name
    self.age=age
    def info(self):
    print(self.name,self.age)

    class Student(Pro):
    def __init__(self,name,age,number):
    super().__init__(name,age)
    self.number=number

    class Teacher(Pro):
    def __init__(self,name,age,year):
    super().__init__(name,age)
    self.year=year

    stu1=Student('bsgbsg',12,2)
    tea1=Teacher('nds',19,29)
    stu1.info()
    tea1.info()

    QQ截图20220921155049

    QQ截图20220921155706

    1
    2
    class C(A,B):
    pass

    方法重写

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class Student(Pro):
    def __init__(self,name,age,number):
    super().__init__(name,age)
    self.number=number
    def info(self):#方法重写,可以类比变量作用域理解
    super().info()#希望调用父类中的方法
    print('学号:',self.number)

    class Teacher(Pro):
    def __init__(self,name,age,year):
    super().__init__(name,age)
    self.year=year
    def info(self):
    super().info()
    print('教龄:',self.year)

    object类

    是所有类的父类,所有类都有object的属性和方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Student():
    def __init__(self,name,age):
    self.name=name
    self.age=age
    def __str__(self):
    return '我的名字是{0},今年{1}岁了'.format(self.name,self.age)
    stu=Student('zhangsan',20)
    print(dir(stu))
    print(stu)#默认调用__str__()方法,返回内存地址;重写后输出自己写的东西,经常用于返回对象的描述
    print(type(stu))

    多态:提高程序得到可扩展性和可维护性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    class Animal(Object):
    def eat(self):
    print('eat')

    class Dog(Animal):
    def eat(self):#重写了父类中的方法
    print('狗')

    class Cat(Animal):
    def eat(self):
    print('猫')

    class Per:
    def eat(self):
    print('人')

    def eat(animal):
    animal.eat()#调用该对象的eat方法

    eat(Per())#即使Per没有继承父类,但只要有eat方法就可以使用

    特殊属性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    class Student():
    def __init__(self,name,age):
    self.name=name
    self.age=age
    def __str__(self):
    return '我的名字是{0},今年{1}岁了'.format(self.name,self.age)
    stu=Student('zhangsan',20)
    print(dir(stu))
    print(stu)#默认调用__str__()方法,返回内存地址;重写后输出自己写的东西,经常用于返回对象的描述
    print(type(stu))

    '''对象.__dict__返回一个字典,查看对象属性'''

    class A:
    pass
    class B:
    pass
    class C(A,B):
    def __init__(self,name,age):
    self.name=name
    self.age=age
    c=C('bsgbsg7',19)
    print(c.__dict__)#返回实例对象的属性
    print(C.__dict__)#返回类对象的属性和方法,方法只在类对象中,实例对象只可以调用

    print(c.__class__)#x.__class__输出对象所属于的类
    print(C.__bases__)#C类与父类的元素,C只可以是类,不可以是实例对象
    print(C.__base__)#输出一个,谁写在前面输出谁

    print(C.__mro__)#类的层次结构

    print(A.__subclasses__())#A的子类列表,注意后面还有个括号

    特殊方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    a=20
    b=18
    c=a+b
    d=a.__add__(b)
    print(c,d)

    class Student:
    def __init__(self,name):
    self.name=name
    '''+运算对应__add__()方法'''
    def __add__(self,other):
    return self.name+other.name
    '''len()函数对应__len__()方法'''
    def __len__(self):
    return len(self.name)

    stu1=Student('bsg')
    stu2=Student('bsg7')

    stu3=stu1+stu2
    print(stu3)#通过修改Student类中的add特殊方法使量对象可以相加
    s=stu1.__add__(stu2)
    print(s)

    print(len(stu1),stu1.__len__())

    QQ截图20220923151820

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Student:
    def __init__(self,name,age):
    self.name=name
    self.age=age

    def __new__(cls, *args, **kwargs):
    obj=super().__new__(cls)
    return obj

    st=Student('bsgbsg',19)
    print(st.__class__)#<class '__main__.Student'>
  • 加速递归

QQ截图20220927142051

QQ截图20220927142215

QQ截图20220927144400

QQ截图20220927144841