这学期上了很多门机器学习的课程,大部分课程都会提到一些python的基本知识,但是好像都没有涉及到python中类的相关内容,我一直感觉“类”就像一个谜一样的东西。正好趁着寒假学一下,顺便把学到的内容以及相关资料码下来。
相关资料
1.感觉这个大佬讲得还挺清晰的Python中的类Class到底怎么写?
这篇推文原参考B站的教学视频链接附上
2. 第二篇参考,这里讲到了关于下划线函数_init_, 和_new_以及_del_的相关内容博客链接
先给出一个示例
这个示例来自相关资料1中的B站视频中留的一道练习题
class Car:
def __init__(self,brand):
self.brand=brand
self.model='xp311'
self.year=2021
def set_model(self,modelnew):
self.model=modelnew
def set_year(self,yearnew):
self.year=yearnew
def pcar(self):
print('车的品牌是{0},车的型号为{1},车的生产年份为{2}'.format(self.brand,self.model,self.year))
- 这里创建了一个实例mycar,在创建实例的时候输入参数‘dazhong’。然后调用类中的方法pcar(),这个类内的方法没有参数,但是仍然需要括号()。
- 这里在上述创建的实例mycar上面,调用set_model(modelnew)和set_year(yearnew)两个方法,并用pcar()方法输出车的信息。
关于类的相关介绍
1.利用关键字class定义类。
(class关键字首字母不能大写,第一次手误打错没发现,一直报错)
2.关键字后面紧跟的是类的名字。
如上面的“Car”,一般类的名字首字母要大写,如果类的名字很长那么通常采用驼峰命名的方式,如“MyCarClass”。
3.类的名字后面表示继承的内容。
括号里填写这个car类是从哪个类继承下来的,如果没有合适的继承类,可以填object类,这个类是所有类都会继承的类;或者也可以直接空着。
class Car(object):
#或者
class Car():
#或者
class Car: #如果没有继承,这个是最常用的形式
4.类里面定义的函数称为 “方法” (method),类外面定义的可执行函数称为function。
最大的区别是,类里面定义的函数第一个参数一定是self,但是在给函数传参的时候不用给self参数的具体值,这个self指的就是实例(instance)本身。
5.类里面有一个特殊的初始化函数,用来初始化类的“属性”。
这个函数为初始化__init__(self)函数。注意这里的双下划线,用肉眼来看好像是init单词左右各一个下划线,其实真正形式是下划线下划线init下划线下划线(self) 这种形式,在init左右各两个下划线,不要少打下划线,不然指定报错。
这里init函数中定义的多余的参数brand,就是创建实例时需要一起给出的参数。
def __init__(self,brand):
.....
因此创建mycar实例(instance)的时候需要传参数。
mycar=Car('dazhong')
6.除了初始化函数外,还可以自己在类中定义一些方法,如上例中的set_model()和set_year().
值得注意的是: 这里定义的“方法”也需要传参,这些参数与init中的参数不同,init中的参数需要在创建实例时就给出;而其他“方法”中的参数,需要在实例调用方法的时候给出。
#mycar是创建的实例instance
#调用set_model()方法时,给modelnew传参
mycar.set_model('ms009')
#同理,调用set_year()方法,给yearnew传参
mycar.set_year(1998)
7.类中的继承和多态。
继承就是在定义新的类的时候在object的位置写上“父类”的名字,然后这个新类就会得到父类中所有定义的 “属性” 和方法(method)。然后在新类中可以重新改写父类中的方法 ,也可以自己另外定义新的方法。
在调用新的类的时候,是否需要传参数以及传几个参数都需要看父类中的init部分内容 。
多态有了继承才有了多态这个概念。我觉得应该是有很多个新类继承同一个父类,大概类似于下面Dog和Cat两个新类,就是呈现了多态的现象。
注意:这里父类和子类之间应该是分支关系,不应该是并列,例如Animal父类下面出现一个Car的新类,该新类继承Animal这个从理论上来说应该是不被允许的,因为Animal的属性方法什么的不太能直接用于Car相关的容。
#myanimal.py
class Animal():
def __init__(self, name):
self.name = name
def greet(self):
print(f'Hello, I am {self.name}.')
#新类Dog继承了Animal这个类
class Dog(Animal):
def greet(self):
print(f'WangWang.., I am {self.name}.')
#新类Cat也继承了Animal这个类
class Cat(Animal):
def greet(self):
print(f'MiaoMiao.., I am {self.name}')
模块的调用
这里定义了这么多类,可以把这些类的内容写入到一个py文件中,然后,如果之后需要用到就直接调用py文件。
假如把这部分写成myanimal.py文件
这个py文件就是一个模块,文件名就是模块名,里面可以写很多类(class),类里面也可以定义很多种方法(method)
注意在运行try.py这个脚本时,因为这个脚本里面调用了myanimal模块,也就需要myanimal.py这个文件。try.py和myanimal.py两个脚本要放在同一个文件夹下面
#try.py
#第一种直接调用myanimal模块
import myanimal
ccat=myanimal.Cat('kitty') #创建实例
#第二种调用模块中的类
from myanimal import Cat
ccat=Cat('kitty')
ccat.greet()
关于if__name__==‘main’:用法
参考链接:Python中if name ==’__ main__’:的作用和原理
重点:一个py文件的执行方式有两种:第一种是作为脚本文件直接执行;第二种是被其他文件调用作为模块import。
注意:if__name__ ==’__ main__’:下面的这部分内容,只有在直接执行脚本文件的时候才会运行;如果被调用import到其他的文件中时,被调用的脚本文件里面判断语句后面的不会执行。