知识速查大全:python面向对象基础
目录
一、面向对象的基本概念
二、类和对象
1.类
2.对象
三、属性(数据)和方法
1.数据
1.1.实例数据
1.2.类数据
2.方法
2.1.实例方法
2.2.类方法
3.数据和方法的综合使用
四、面向对象三大特性
1.封装
2.继承
2.1.单继承
2.2.多继承
2.3.混合类
2.4.方法解析顺序(MRO)
3.多态
五、数据访问级别
1.公有
2.私有
3.保护
六、类的成员
特点
七、魔法函数
1.__init__
2.__str__
3.数学比较
4.__len__
5.__new__(cls)、__del__
6.上下文管理器
总结
一、面向对象的基本概念
面向对象编程(Object-Oriented Programming,OOP)是一种编程范式,它以"对象"为核心组织代码和数据,他更适合一些复杂项目的开发,通过封装方法和属性,让代码的复用性增强,提高了开发效率。
二、类和对象
类是抽象的,对象是具体的。
1.类
类是创建对象的蓝图或模板,它定义了对象的属性和行为。下面是定义一个类:
class MyClass:"""一个简单的类示例"""pass
2.对象
对象是类的实例,是根据类创建的具体实体。以下是对上述类的一个实例化对象:
obj = MyClass()
三、属性(数据)和方法
1.数据
所谓数据,就是事物所具有的一定的特征。
1.1.实例数据
实例数据属于特定实例的变量,通过self
在方法中定义和访问。例如,下面定义了一个学生Student类,在类里面定义了两个属性,分别是self.name和self.age,这个就是实例数据。
class Student:def __init__(self, name, age):self.name = name # 实例属性self.age = age # 实例属性stu1 = Student("张三", 20)
stu2 = Student("李四", 22)
print(stu1.name) # 输出: 张三
print(stu2.name) # 输出: 李四
1.2.类数据
类数据属于类本身的变量,所有实例共享同一个类属性,定义在类内部但在方法外部。我们在学生类里面定义了类数据school,在类外部实例化两个对象,运行结果是都能打印出这个属性值。
class Student:school = "清华大学" # 类属性def __init__(self, name):self.name = namestu1 = Student("王五")
stu2 = Student("赵六")
print(stu1.school) # 输出: 清华大学
print(stu2.school) # 输出: 清华大学
2.方法
所谓方法,就是事物所具有的一定的行为。
2.1.实例方法
实例方法的第一个参数必须是self
,表示当前实例,可以访问和修改实例属性。下面的bark就是我们的实例方法,self表示当前的实例。
class Dog:def __init__(self, name):self.name = namedef bark(self): # 实例方法print(f"{self.name}在汪汪叫!")dog = Dog("阿黄")
dog.bark() # 输出: 阿黄在汪汪叫!
2.2.类方法
类方法使用@classmethod
装饰器,第一个参数是cls
,表示当前类,可以访问和修改类属性。get_count(cls)这个方法第一个参数是cls,说明当前是类这个级别,在类外面以对象的形式调用。
class Student:count = 0 # 类属性@classmethoddef get_count(cls):return cls.countdef __init__(self):Student.count += 1stu1 = Student()
stu2 = Student()
print(Student.get_count()) # 输出: 2
3.数据和方法的综合使用
问题:创建一个圆Circle类,为该类提供一个初始化方法,用于初始化半径;为该类提供两个方法,方法一用 于求圆的面积,方法二用于求圆的周长。
class Circle:PI = 3.14# 初始化方法def __init__(self, radius):self.radius = radiusdef get_area(self):return Circle.PI * self.radius ** 2def get_perimeter(self):return 2 * Circle.PI * self.radiusc = Circle(1)
print(c.get_area())
print(c.get_perimeter())
四、面向对象三大特性
1.封装
将数据和操作数据的方法绑定在一起即为封装。封装在类中非常常见,封装完成后,进行类的实例化即可。
class Product:def __init__(self, name, price):self.name = nameself.price = pricedef get_price(self):return self.priceclass Food:def __init__(self, weight):self.weight = weightdef get_qian(self):print(Product("食物", 49.9).price)
f = Food(20)
f.get_qian() # 输出49.9
2.继承
2.1.单继承
一个子类只继承一个父类,这样的继承叫做单继承。
# 继承
class Animal:def __init__(self, age):self.age = agedef __str__(self):return "hello"def shark(self):print("动物都会叫")a = Animal(5)
print(a, a.age)
a.shark()class Dog(Animal):def __init__(self, age, name):super().__init__(age)self.name = namedef __str__(self):return "这是一只狗狗"def shark(self):print("狗正在叫喊")d = Dog(7, "lida")
print(d, d.age, d.name)
d.shark()class AQ(Dog):def __init__(self, age, name, height):super().__init__(age, name)self.height = heightdef __str__(self):return "这是一只Dog队"def shark(self):print("团队活动正在精心准备进行")aq = AQ(9, "huange", 2.5)
print(aq, aq.age, aq.name, aq.height)
aq.shark()
2.2.多继承
多继承的一个子类可以继承多个父类。
class Father:def __init__(self, money):self.money = moneydef get_money(self):print(self.money)class Mother:def __init__(self, beautiful):self.beautiful = beautifuldef get_beautiful(self):print(self.beautiful)class Son(Father, Mother):def __init__(self, money, beautiful):# # 多继承中,子类只能继承(识别)第一个父类# # super().__init__(money)# # super().__init__(beautiful)# # 多继承使用类调用,要有selfFather.__init__(self, money)Mother.__init__(self, beautiful)def show(self):return f"共计{self.money}"s = Son("100", "漂亮")
s.get_money()
s.get_beautiful()
当处于多继承时,子类使用超类调用,只能继承(识别第一个父类),因此,我们一般会通过“父类对象.__init__()”类调用的方法进行完整的继承。
2.3.混合类
一种特殊的多继承用法,用于添加功能,通常是以Mixin结尾。
class Life:def __init__(self, hb):self.hb = hbdef __str__(self):return f"生命值{self.hb}"class Animal:passclass SwimmingAbleMixin:def swim(self):print(f"鱼可以游泳")class Fish(Life, SwimmingAbleMixin):passf = Fish("100")
print(f) # 生命值100
f.swim() # 鱼可以游泳
2.4.方法解析顺序(MRO)
Python使用C3算法确定多继承时的查找顺序。
class A:passdef __str__(self):return "A"class B11:pass# def __str__(self):# return "B11"class B12:def __str__(self):return "B12"class B1(B11, B12):pass# def __str__(self):# return "B1"class B2:pass# def __str__(self):# return "B2"class B(B1, B2):pass# def __str__(self):# return "B"class C(B, A):pass# def __str__(self):# return "C"c = C()
print(c)
3.多态
多态就是不同类的对象对同一消息做出不同的响应。一般都是编译型语言拥有的概念。
class Employee:def __init__(self, name, salary):self.name = nameself.salary = salarydef get_salary(self):raise NotImplemented("子类必须重写父类")class Manage(Employee):def __init__(self, bonus, name, salary):super().__init__(name, salary)self.bonus = bonusdef get_salary(self):total = self.salary + self.bonusreturn f"{self.name}的总工资为{total}"m = Manage(500, "刘强", 8000)
print(m.get_salary()) # 输出:刘强的总工资为8500
上述代码创建另一个基类和一个子类,两个类都有同一种方法get_salary(),但是需要通过子类重写父类实现。
- 父类中的raise NotImplemented("子类必须重写父类")表示子类中必须要实现此方法,否则程序会出错。
- 子类中super().__init__(name, salary)表明继承父类中的两个属性(数据)。
五、数据访问级别
1.公有
默认格式,类内通过self访问,类外通过对象访问。
class MyClass:def __init__(self):self.public_var = "I'm public"def public_method(self):return "Public method"obj = MyClass()
print(obj.public_var) # 可以直接访问
print(obj.public_method()) # 可以直接调用
2.私有
__开头,类内以self访问,类外不可访问。
class MyClass:def __init__(self):self.__private_var = "I'm private"def __private_method(self):return "Private method"obj = MyClass()
# print(obj.__private_var) # 直接访问会报错
# print(obj.__private_method()) # 直接调用会报错# 通过名称修饰后的名称仍可访问(但不应该这样做)
print(obj._MyClass__private_var) # 可以访问
print(obj._MyClass__private_method()) # 可以调用
3.保护
_开头,本类内可以访问,本类外也可以访问,但不推荐;通常是在子类中使用。
class MyClass:def __init__(self):self._protected_var = "I'm protected"def _protected_method(self):return "Protected method"obj = MyClass()
print(obj._protected_var) # 仍然可以访问,但不建议
print(obj._protected_method()) # 仍然可以调用,但不建议
六、类的成员
除了上述介绍的类的成员,下面还有一种类成员,就是静态方法。静态方法(Static Method)是一种属于类但不属于类的任何特定实例的方法。这意味着你可以调用静态方法而不创建类的实例。静态方法通常用于实现那些不依赖于类实例状态的工具方法或辅助方法。
class MyClass:@staticmethoddef static_method():print("Called static_method")@staticmethoddef sum(a, b):print(a + b)@staticmethoddef max(a, b):return a if a > b else bMyClass.static_method()
MyClass.sum(3, 5)
print(MyClass.max(12, 5))
上述代码中,我们在调用静态方法时,并没有进行实例化,而是通过函数名直接调用。
特点
-
无需实例:你可以直接通过类名调用静态方法,无需创建类的实例。
-
不接受
self
或cls
:静态方法不会自动接收任何类或实例作为第一个参数。 -
用途:静态方法通常用于实现那些不需要访问类实例状态的函数,例如工厂方法、工具函数等。
七、魔法函数
1.__init__
__init__函数用于初始化self。
class Light:def __init__(self):"""初始化函数:用于初始化selfself就是类执行产生的对象"""self.color = "红色"print(id(self))def set_light(self, color):self.color = colorprint(self.color)def get_light(self):print(self.color)创建对象l1
l1 = Light()
l1.set_light("绿色")
print(id(l1), l1.color)print("++++++++++++++")创建对象l2
l2 = Light()
l2.get_light()
2.__str__
__str__函数返回的结果必须是字符串,也是自动调用。
class Person:def __init__(self, name, age):self.name = nameself.age = agedef __str__(self):return f"Person(name='{self.name}', age={self.age})"p = Person("Alice", 30)
print(p) # 输出: Person(name='Alice', age=30)
3.数学比较
数学比较的魔法函数有__gt__、__ge__、__lt__、__le__、__eq__和__ne__。所有的魔法函数不需要主动调用,以__**__为格式。
class Person:def __init__(self, name, age):self.name = nameself.age = agedef __str__(self):"""对象的字符串表示:return: 字符格式"""return f"{self.name}:{self.age}"def __gt__(self, other):"""重写,实例比较的>:param other::return:"""return self.age > other.agedef __ge__(self, other):return self.age >= otherdef __lt__(self, other):"""小于:param other::return:"""return self.age < other.agedef __le__(self, other):return self.age <= other.agedef __ne__(self, other):return self.age != other.agedef __eq__(self, other):return self.age == other.agep1 = Person("abc", 20)
print(p1)
p2 = Person("jsp", 26)
print(p1 <= p2)
4.__len__
__len__用于定义对象的长度。当对对象调用内置的 len()
函数时,Python 会自动调用该对象的 __len__
方法。
class MyCollection:def __init__(self, items):self.items = itemsdef __len__(self):return len(self.items)collection = MyCollection([1, 2, 3, 4, 5])
print(len(collection)) # 输出: 5
5.__new__(cls)、__del__
构造函数:创建类的新实例对象;析构函数:用于对象销毁的特殊方法
class Animal:# 必须返回一个类的实例,否则init__,方法不会被调用。def __new__(cls, *args, **kwargs):# cls 是当前类对象,必须作为参数传入instance = super().__new__(cls)return instancedef __init__(self):print("初始化函数执行了", id(self))def __del__(self):print("正在销毁...")
# 先调用 __new__ 创建对象,再调用 __init__ 初始化对象
a = Animal()
print(a, id(a))
6.上下文管理器
__enter__:实现资源的获取;
__exit__:实现资源的释放。
class Myopen:def __init__(self, filename, mode):self.filename = filenameself.mode = modeself.file = Nonedef __enter__(self):self.file = open(self.filename, self.mode)return self.filedef write(self, msg):self.file.write(msg)def __exit__(self, exc_type, exc_val, exc_tb):# exc_type:异常类型# exc_val:异常值# exc_tb:追踪信息if self.file:self.file.close()with Myopen("myfile.txt", "w") as f:f.write("Hello world!")
总结
面向对象编程(OOP)是一种以对象为核心的编程范式,其核心概念包括类与对象、属性与方法、三大特性(封装、继承、多态)以及数据访问控制等。类作为对象的抽象模板,通过定义属性和方法来描述实体的特征和行为,其中属性分为实例数据(对象独有)和类数据(类共享),方法则包括实例方法(操作实例数据)、类方法(操作类数据)等。面向对象三大特性中,封装通过访问控制(公有、私有、保护)隐藏实现细节;继承支持单继承和多继承,通过方法解析顺序(MRO)解决多继承冲突;多态则允许不同类对象对同一方法产生不同行为。类的特殊成员如魔法函数(如__init__构造对象、__str__定义字符串表示、__len__支持长度计算等)赋予类更灵活的行为能力。上下文管理器(__enter__/__exit__)等高级特性进一步扩展了对象的功能边界。这些概念共同构成了面向对象编程的完整体系,通过抽象、模块化和代码复用提升软件的可维护性和扩展性。