本文将介绍模块与类的区别,如何定义类以及如何继承父类的方法。
1
模块与类的区别

模块定义:
在Python中,模块是一组相关的代码的集合,它们被封装在一个文件中。模块通常包含函数、变量和类的定义。通过使用import语句,我们可以在其他程序中引入模块,并使用其中的函数和类。模块提供了一种将代码组织成可复用的逻辑单元的方式。
类的定义:
在面向对象编程中,类是一个用于创建对象的蓝图或模板。类定义了对象的属性和方法。通过实例化类,我们可以创建对象,并使用对象的方法来执行特定的操作。类提供了一种将数据和行为封装在一起的方式。
虽然模块和类在Python中都用于组织和封装代码,但它们在功能和使用方式上有一些重要的区别。
功能区别:
模块通常用于组织一组相关的函数、变量和类的定义,以便在多个程序中重复使用。它提供了一种将功能性代码组织成逻辑单元的方式。
类则用于创建对象和封装数据和行为。它提供了一种将数据和相关的操作封装在一起的方式,以便创建和使用具有特定功能的对象。
使用方式区别:
通过使用import语句,我们可以在其他程序中引入模块,并使用其中的函数和类。模块可以有层次结构,我们可以从导入的模块中导入其它模块。
类则通过实例化来使用。我们可以创建类的对象,并使用对象的方法来执行特定的操作。每个类的实例都相互独立。
命名空间区别:
模块和类都具有自己的命名空间。模块的命名空间由模块中定义的函数、变量和类组成。类的命名空间由类的属性和方法组成。
基于类创建对象,每个对象都自动具备通用行为,并且类创建对象的过程也称为实例化。
类的定义与声明是同时进行的,在用class关键字声明一个类之后,此类就被定义了。

2
声明类

声明类的主要目的是创建一种可复用的“对象模板”,用于在程序中封装数据和行为。
class后面接着是类名ClassName,类名的开头通常是大写。
class ClassName(bases_classes)类名后面的(bases_classes)表示:这个类是由哪个类继承来的,如果没有合适的继承类,就使用object类,object类是所有类都会继承的基类。
类文档字符串:是对类所进行的说明,可以通过ClassName.__doc__查看。如下:
class Book(object):'书籍类' #类文档字符串bookList = ['python','java','c++','ruby']for book in bookList:print(book)

3
定义类

def不仅能定义函数,还可以定义类里面的各种方法声明。__init__()定义的变量,在的函数中后面无需再定义了,因为init已经初始化了,是默认执行的,例如下述代码。
class Book(object):'书籍类'def _init_(self,name,author,data,version):self.name = nameself.author = authorself.data = dataself.version = versiondef sell(bookName,price):print("%s的销售价格为%d" %(bookName,price))
类中的方法一定要通过实例的句点方法去调用。
在实例化一个对象后,Python 会检查是否实现了__init__()方法。如果没有实现__init__()方法,则不会做其它的操作,直接返回对象,实例化过程完毕。而__init__()方法是用来给类本身初始化的,支持带参数的初始化。 一定要先有init,然后定义好self的属性参数,后面的方法部分如果引入的不是实例本身的属性,需要在声明加入进去;否则不用加入,括号内只有self即可。
class Book:def __init__(self,bookname,price,author): #一定要先有init,然后定义好self的参数self.bookname = booknameself.price = priceself.author = authordef sell(self):#方法部分没有引入新的属性,只有selfprint("%s书本的价格为%d" %(self.bookname,int(self.price)))book = Book("python","45","aas") #创建实例book.sell()
类的数据属性只与类绑定,不属于任何实例。类的数据属性也可以称为静态变量,它通常用来跟踪与类相关的值。类的数据属性使用的并不多,一般都是用实例数据属性。类中还有很多特殊属性,具体如下:
ClassName.__name__:类ClassName的名字;
ClassName.__doc__:类ClassName的文档字符串;
ClassName.__bases__:类ClassName的所有父类构成的元组;
ClassName.__dict__:类ClassName的属性;
ClassName.__module__:类ClassName定义所在的模块;
Instance.__class__:实例Instance所对应的类。
self 到底是啥?
定义方法时,self总是作为第一个参数传递的。
self代表实例本身,
self.变量代表调用此实例的变量,
self.方法代表调用实例的方法。
因为声明方法时已经传入self,所以在调用时self就不用明确传入了,此时实例是隐含的。
#调用绑定方法:第一个参数 self 会被自动传入(即该实例本身)。调用时不需要显式传递 self。class bindExample:def bindMethod(self):print("绑定方法调用实例")be = bindExample()be.bindMethod()
类方法
在 Python 中,类方法(class method) 是一种与类本身绑定的方法,而不是与类的某个具体实例绑定。它通过装饰器 @classmethod 定义,其第一个参数自动接收类对象(通常命名为 cls),而不是实例(self)。
在声明类方法的时候,使用函数修饰符@classmethod。固定搭配
class ClassMethod:@classmethoddef classtest(cls):print(cls)print("这是类方法")cm = ClassMethod()cm.classtest()
输出结果为:
<class '__main__.ClassMethod'>这是类方法
经典用途
替代构造函数(工厂方法)
当需要多种方式创建实例时,类方法非常有用:
class Date:def __init__(self, year, month, day):self.year = yearself.month = monthself.day = day@classmethoddef from_string(cls, date_str):# 从 "YYYY-MM-DD" 字符串创建实例year, month, day = map(int, date_str.split('-'))return cls(year, month, day)@classmethoddef today(cls):# 模拟获取当前日期(简化版)return cls(2026, 1, 13)# 使用d1 = Date.from_string("2026-01-13")d2 = Date.today()
静态方法
在 Python 中,静态方法(static method) 是一种定义在类中、但不依赖于类或实例状态的方法。它既不需要访问 self(实例),也不需要访问 cls(类),因此可以像普通函数一样使用,只是逻辑上属于该类的命名空间。
在声明静态方法的时候,使用函数修饰符@staticmethod。是固定搭配
class StaticMethood:@staticmethoddef statictest():print("这是静态函数")StaticMethood.statictest()
什么时候用静态方法?
当你有一个函数逻辑上属于某个类(比如是该类的辅助功能),但不需要访问类或实例的数据时。
比如:日期格式校验、数学计算、字符串处理等通用工具函数。
导入模块(所有类)
import ModuleName通常这个模块就是要导入的那个类所在的文件*.py,所以调用类的方法为:
object = ModuleName.ClassName()object.属性object.方法
我们在导入时一定要知道我们需要的这个类或方法属于这个模块。
导入单个或多个类
from ModuleName import ClassName1,ClassName2,...调用类的属性和方法的语句:
object = ClassName()object.属性object.方法
在这种方法中,若导入的类名相同,则后面导入的类将会覆盖前面导入的类。
导入模块中所有类
from ModuleName import *在这种方法中,若导入的模块中含有名字相同的类,则类与类之间也会产生覆盖。
object = ClassName()object.属性object.方法

4
继承父类

通过继承,子类可以继承其父类所有的属性和方法,这在很大程度上增强了代码的重用。
举个例子:动物就是父类,它具有着所有动物都有的共性,而鱼和豹子是子类,它们不仅具有共性:呼吸、奔跑、觅食,还有着自己独特的特征:游泳、爬树。
1
定义
父类
也称基类,其声明方法与一般的类的声明方法一样。父类中存在着一些公共的属性和方法,子类继承于父类。
子类
子类继承于父类,拥有父类中的属性和方法,它自己也可根据实际情况声明一些属于自己的属性和方法。

2
子类声明办法
class subClass(parentClass1,parentClass2,……):class_suite
类名后的括号里填的就是所继承的父类的名称。
class ParentClass:static_var = 100def parentMethod(self):print("这是父类")class SubClass(ParentClass):def subMethod(self):print("这是子类")sc = SubClass()print(sc.static_var)sc.parentMethod()sc.subMethod()print("%s所属的父类为%s" %(sc.__class__,SubClass.__bases__))
结果为:
100这是父类这是子类<class '__main__.SubClass'>所属的父类为(<class '__main__.ParentClass'>,)
没有父类的子类base属性为空。
如果继承导入模块里的类,继承的时候需要:模块名.父类名

3
继承父类+覆盖方法(overriding)
在子类继承父类的方法时,若子类需要这个方法具有不同的功能,那么可以通过覆盖(overriding)来重写这个方法。
只需要在子类里再写一个与父类中一样的方法,实现自己想要实现的功能,就能覆盖。
class Parent:def sayHello(self):print("hello,i am class parent")class Subclass(Parent):def sayHello(self):print("hello,i am class subclass")sc = Subclass()sc.sayHello()
#输出hello,i am class subclass
Subclass继承了Parent类,但是因为它在类中重写了sayHello(),所以在创建实例后,调用的是重写后的sayHello()。
在重写了父类中的方法后,也可以调用父类中的被重写方法。
这时就是去调用一个未绑定的父类方法。例如:
Parent.sayHello(sc)#输出:hello,i am class parent#还是父类的结果,说明子类改写方法不影响父类方法
还可以在子类的重写方法里显示调用。
class Parent:def sayHello(self):print("hello,i am class parent")class Subclass(Parent):def sayHello(self):Parent.sayHello(self)print("hello,i am class subclass")sc = Subclass()sc.sayHello()
#输出hello,i am class parenthello,i am class subclass
但是最好的方法是在子类的重写方法里使用super()内建方法。

4
多重继承
多重继承就是允许子类继承多个父类,子类可以调用多个父类的方法和属性。
但是,当多个父类拥有相同方法名的方法时,我们通过方法名调用父类方法就有一定的顺序。
class A(object):def test(self):print("this is A.test()")class B(object):def test(self):print("this is B.test()")def check(self):print("this is B.check()")class C(A,B):passclass D(A,B):def check(self):print("this is D.check()")class E(C,D):pass

在我们调用E.test()时,在类A和类B中都存在这个方法。但是由于在多重继承中遵循广度优先的方式(先探索节点级数较浅的节点),所以程序最先搜索类E,然后再搜索类C和类D。如果还没找到,再到类A中查找。若类A中存在这个方法,则调用这个方法,若在类A中也没有找到,则再到类B中查找。
调用E.test()结果为:
this is A.test()如果调用E.check()方法,那么先到类E中查找,然后在类C中查找,再到类D中查找。在类D中找到这个方法,调用这个方法。
调用E.check()的结果为:
this is D.check()