目录
类和对象的概念
类(Class)
对象(Object)
(一)属性(Attributes)
(a).实例属性(Instance Attributes)
(b).类属性(Class Attributes)
(二)方法(Methods)
(a)实例方法(Instance Methods)
(b)类方法(Class Methods)
(c)静态方法(Static Methods)
(三) 继承(Inheritance)
(四) 多态(Polymorphism)
(五) 封装(Encapsulation)
补充
(1)特殊方法(Magic Methods)或双下划线方法(Dunder Methods)
(2)装饰器与面向对象
(3)类的组合
(4)元类(Metaclasses)
类和对象的概念
-
类(Class)
- 类是一种抽象的数据类型,它定义了一组具有相同属性(Attributes)和方法(Methods)的对象的模板。可以把类想象成制作某种物品的蓝图。例如,定义一个 “汽车(Car)” 类,这个类可以包含汽车的属性,如颜色(color)、品牌(brand)、速度(speed)等,以及汽车可以执行的方法,如加速(accelerate)、刹车(brake)等。
- 在 Python 中,类的定义使用
class
关键字。例如:
class Car:def __init__(self, color, brand):self.color = colorself.brand = brandself.speed = 0
-
对象(Object)
- 对象是类的一个具体实例。根据上面的 “汽车(Car)” 类的蓝图,可以创建出多个具体的汽车对象。比如,
car1 = Car("red", "Toyota")
和car2 = Car("blue", "Ford")
,这里car1
和car2
就是Car
类的两个对象,它们分别具有自己的颜色、品牌和初始速度(在__init__
方法中初始化为 0)等属性。
- 对象是类的一个具体实例。根据上面的 “汽车(Car)” 类的蓝图,可以创建出多个具体的汽车对象。比如,
(一)属性(Attributes)
(a).实例属性(Instance Attributes)
- 实例属性是属于对象个体的属性。在上面的
Car
类中,color
、brand
和speed
就是实例属性。每个Car
类的对象都可以有不同的颜色和品牌,并且它们的速度也可以独立变化。通过self
关键字来访问和修改实例属性。例如:
class Car:def __init__(self, color, brand):self.color = colorself.brand = brandself.speed = 0def accelerate(self, increment):self.speed += increment
在accelerate
方法中,通过self.speed
来访问和修改对象的速度属性。
(b).类属性(Class Attributes)
- 类属性是属于类本身的属性,被该类的所有对象所共享。例如,定义一个
Car
类的类属性wheels
来表示汽车的轮子数量,因为通常汽车的轮子数量是固定的(假设为 4),对于所有Car
类的对象都是一样的。
class Car:wheels = 4def __init__(self, color, brand):self.color = colorself.brand = brandself.speed = 0
可以通过Car.wheels
来访问类属性,所有Car
类的对象都共享这个属性值。
(二)方法(Methods)
(a)实例方法(Instance Methods)
- 实例方法是定义在类中的函数,用于操作对象的实例属性或者执行与对象相关的操作。实例方法的第一个参数通常是
self
,它代表调用该方法的对象本身。例如在Car
类的accelerate
方法中,self
表示正在加速的那个汽车对象。
class Car:def __init__(self, color, brand):self.color = colorself.brand = brandself.speed = 0def accelerate(self, increment):self.speed += incrementdef brake(self, decrement):if self.speed >= decrement:self.speed -= decrementelse:self.speed = 0
这里accelerate
和brake
都是实例方法,它们通过self
来访问和修改对象的speed
属性。
(b)类方法(Class Methods)
- 类方法是与类本身相关的方法,而不是与类的某个具体对象相关。类方法使用
@classmethod
装饰器来定义,并且第一个参数通常是cls
,代表类本身。类方法可以用于创建工厂方法或者修改类属性等操作。例如:
class Car:wheels = 4@classmethoddef change_wheels(cls, new_wheels):cls.wheels = new_wheels
通过Car.change_wheels(6)
可以修改Car
类的wheels
类属性的值。
(c)静态方法(Static Methods)
- 静态方法是定义在类中的普通函数,它不需要访问实例属性或者类属性,也不需要
self
或者cls
参数。静态方法通常用于实现一些与类相关但又不依赖于类的实例或者类本身的状态的功能。例如:
class Car:@staticmethoddef is_motor_vehicle():return True
is_motor_vehicle
静态方法只是简单地返回一个布尔值,表示汽车是机动车,它不依赖于任何Car
类的实例或者类属性。
(三) 继承(Inheritance)
- 继承是面向对象编程中的一个重要特性,它允许创建一个新类(子类),子类继承了父类的属性和方法,并且可以添加新的属性和方法或者重写父类的现有属性和方法。例如,定义一个 “电动汽车(ElectricCar)” 类,它继承自 “汽车(Car)” 类。
class ElectricCar(Car):def __init__(self, color, brand, battery_capacity):super().__init__(color, brand)self.battery_capacity = battery_capacitydef charge(self):print("Charging the electric car.")
在ElectricCar
类中,通过super().__init__(color, brand)
调用父类Car
的__init__
方法来初始化继承自父类的属性(color
和brand
),同时添加了新的属性battery_capacity
和新的方法charge
。
(四) 多态(Polymorphism)
- 多态是指不同类型的对象对同一消息(方法调用)做出不同的响应。在 Python 中,多态通常通过方法重写(在子类中重新定义父类的方法)来实现。例如,
Car
类和ElectricCar
类都有accelerate
方法,但是它们的实现细节可能不同。
class Car:def __init__(self, color, brand):self.color = colorself.brand = brandself.speed = 0def accelerate(self, increment):self.speed += increment
class ElectricCar(Car):def __init__(self, color, brand, battery_capacity):super().__init__(color, brand)self.battery_capacity = battery_capacitydef accelerate(self, increment):# 假设电动汽车加速方式不同self.speed += increment * 2
当调用car.accelerate(10)
(car
是Car
类的对象)和electric_car.accelerate(10)
(electric_car
是ElectricCar
类的对象)时,它们会根据各自类中accelerate
方法的定义做出不同的加速行为,这就是多态的体现。
(五) 封装(Encapsulation)
- 封装是将数据(属性)和操作数据的方法组合在一起,并对外部隐藏对象的内部细节。在 Python 中,可以通过在属性和方法名前面添加双下划线(
__
)来实现一定程度的封装。例如:
class Car:def __init__(self, color, brand):self.__color = colorself.__brand = brandself.__speed = 0def accelerate(self, increment):self.__speed += incrementdef get_color(self):return self.__colordef set_color(self, new_color):self.__color = new_color
在这个Car
类中,__color
、__brand
和__speed
属性被封装起来,外部不能直接访问这些属性,但是可以通过get_color
和set_color
等方法来间接访问和修改属性的值。这样可以保护对象的内部状态,防止外部代码随意修改,提高代码的可维护性和安全性。
补充
(1)特殊方法(Magic Methods)或双下划线方法(Dunder Methods)
这些方法在 Python 中具有特殊的意义,它们通常以双下划线开头和结尾。例如 __str__
和 __repr__
方法用于对象的字符串表示。
class Car:def __init__(self, color, brand):self.color = colorself.brand = branddef __str__(self):return f"Car: {self.brand} in {self.color}"def __repr__(self):return f"Car({self.color}, {self.self.brand})"
__str__
方法主要用于提供给用户友好的对象字符串表示,比如在使用 print
函数打印对象时会调用该方法。__repr__
方法则更侧重于提供对象的精确表示,通常在交互式环境中直接输入对象时显示,也用于对象的序列化等场景,有助于调试和记录对象的状态。
还有其他一些特殊方法,如 __add__
用于定义对象的加法操作。例如对于自定义的向量类,可以定义 __add__
方法来实现向量相加的逻辑:
class Vector:def __init__(self, x, y):self.x = xself.y = ydef __add__(self, other):return Vector(self.x + other.x, self.y + other.y)
这样就可以像使用内置数据类型一样对自定义的 Vector
类对象进行加法运算:v1 = Vector(1, 2); v2 = Vector(3, 4); v3 = v1 + v2
。
(2)装饰器与面向对象
装饰器可以应用于类和类的方法,以扩展其功能。例如,@property
装饰器是一种常用的装饰器,它可以将一个方法转换为一个类似属性的访问方式,同时可以在方法内部添加一些逻辑,比如数据验证等。
class Person:def __init__(self, name, age):self._name = nameself._age = age@propertydef age(self):return self._age@age.setterdef age(self, new_age):if new_age > 0:self._age = new_ageelse:raise ValueError("Age must be positive.")
这里通过 @property
装饰器将 age
方法转换为属性,使得可以像访问属性一样获取年龄值(person.age
),同时通过 @age.setter
装饰器定义了属性的设置方法,在设置年龄时可以进行数据验证。
(3)类的组合
除了继承,类的组合也是构建复杂对象关系的重要方式。类的组合是指一个类将其他类的对象作为自己的属性,从而利用其他类的功能来构建更复杂的功能。
例如,一个 Car
类可以包含一个 Engine
类的对象作为其发动机属性:
class Engine:def start(self):print("Engine started.")def stop(self):print("Engine stopped.")class Car:def __init__(self, color, brand):self.color = colorself.brand = brandself.engine = Engine()def start_car(self):self.engine.start()def stop_car(self):self.engine.stop()
通过这种组合方式,Car
类可以利用 Engine
类的功能来实现汽车的启动和停止操作,而不需要继承 Engine
类,这种方式在一些情况下可以提供更灵活的设计,避免了复杂的继承层次带来的问题。
(4)元类(Metaclasses)
元类是创建类的类。在 Python 中,一切皆对象,类也是对象,而元类就是用来创建这些类对象的。默认情况下,Python 使用 type
作为元类来创建普通的类。但可以自定义元类来控制类的创建过程,例如添加自定义的属性或方法到创建的类中,或者修改类的定义方式。
class MyMeta(type):def __new__(cls, name, bases, attrs):attrs['new_attribute'] = "This is a new attribute added by metaclass"return super().__new__(cls, name, bases, attrs)class MyClass(metaclass=MyMeta):passprint(MyClass.new_attribute)
- 自定义元类
MyMeta
代码解读:
class MyMeta(type):def __new__(cls, name, bases, attrs):attrs['new_attribute'] = "This is a new attribute added by metaclass"return super().__new__(cls, name, bases, attrs)
这里定义了一个名为 MyMeta
的自定义元类,它继承自 type
(因为元类本身就是创建类的类,type
是 Python 中默认用于创建类的元类基础)。在 MyMeta
类里重写了 __new__
方法,此方法在类创建时被调用。
在 __new__
方法内,接收了几个关键参数:
cls
:代表当前的元类自身(在这里就是MyMeta
类)。name
:是即将要创建的类的名称(在后续示例中对应MyClass
的类名)。bases
:是一个包含了新类要继承的基类的元组(示例中MyClass
没有显式指定基类继承,该参数对应为空元组等情况)。attrs
:是一个字典,里面存放着即将创建的类的属性和方法等信息(类似类的命名空间)。
在__new__
方法中,往attrs
字典里添加了一个新的键值对,键是new_attribute
,值是"This is a new attribute added by metaclass"
,意味着通过这个元类创建的类将会拥有这个新属性。最后,调用父类(也就是type
类)的__new__
方法来实际创建类对象,并返回创建好的类对象。
- 使用自定义元类创建
MyClass
类及验证:
class MyClass(metaclass=MyMeta):passprint(MyClass.new_attribute)
定义 MyClass
类时,通过 metaclass=MyMeta
指定了使用自定义的 MyMeta
元类来创建它。由于 MyMeta
元类在创建类时添加了 new_attribute
属性,所以后续可以直接通过 MyClass.new_attribute
来访问这个属性,并打印出对应的值 "This is a new attribute added by metaclass"
。
在这个例子中,自定义的元类 MyMeta
在创建 MyClass
类时添加了一个新的属性 new_attribute
。虽然元类在日常编程中使用相对较少,但在一些高级的框架开发和特定的编程模式中有着重要的应用,如 Django 框架中的一些模型类的创建就利用了元类的特性来实现数据库表的映射等功能。