1.类和对象的基础语法

下面是用Python编写类的基本语法

class class_name:
	statements

这里的statements可以包括一个或多个语句。statements不能为空,但可以使用pass关键字来表示没有操作。当你不想对类的行为进行定义时,可以使用pass作为占位符。

可以这样定义Car类:

class Car:
	pass

可以这样定义Dog类和Cat类

class Dog:
	pass
	
class Cat:
	pass

那我们如何使用Python的类呢?可以创建该类的任意数量的实例。以下语句创建了三个Car类的实例:

car1 = Car()
car2 = Car()
car3 = Car()

也可以创建Dog类的实例:

my_dog = Dog()
yr_dog = Dog()

我们可以为类创建变量,这些变量称为类变量,类的所有实例都共享这些变量。

例如,假设Car类是这样定义的:

class Car:
	accel = 3.0
	mpg = 25

现在输出Car类的每个实例:

print('car1.accel=',car1.accel)
print('car2.accel=',car2.accel)
print('car1.mpg=',car1.mpg)
print('car2.mpg=',car2.mpg)

输出结果如下:

image-20250831165544312

需要注意的是,Car类的任何实例都可为变量accel赋值。这样做会覆盖类变量的值(这里是3.0)。我们可以创建一个实例my_car,并为类变量accel赋值

my_car = Car()
yr_car = Car()
my_car.accel = 5.0
print(f"my_car.accel={my_car.accel}")
print(f"yr_car.accel={yr_car.accel}")

输出结果如下:

image-20250831165818196

在my_car对象中,accel已经成为实例变量;在yr_car中它仍是一个类变量

image-20250831170024117

2.Python中实例变量

在Python中,实例变量的添加方法有如下几种:

  • __init__方法中初始化

__init__是类的构造方法,在创建实例时会自动调用,在此方法通过self.变量名定义的变量,会成为所有实例的"默认实例变量"。

语法

class 类名:
	def __init__(self,参数1,参数2, ...):
		#self表示当前实例
		self.变量名1 = 参数1	#从外部传入的值
		self.变量名2 = 参数2
		self.变量名3 = 默认值	#固定默认值(无需外部传入)

示例

class Student:
    def __init__(self,name,age):
        self.name = name
        self.age = age
        self.score = 0

stu1 = Student("Alice",18)
stu2 = Student("Bob", 19)

print(stu1.age) #输出18
print(stu2.age) #输出19
  • 实例创建后动态添加

在实例创建之后,通过实例名.变量名直接为单个实例绑定新变量

示例

class Student:
    def __init__(self,name,age):
        self.name = name
        self.age = age
        self.score = 0

stu1 = Student("Alice",18)
stu1.hobby = "reading"

print(stu1.hobby) #输出reading
  • 通过 __setattr__方法(底层拦截赋值)

__setattr__是Python的魔法方法,用于拦截所有self.变量名 = 值实例.变量名 = 值的赋值操作,通过重写该方法,可以自定义实例变量的添加逻辑

示例

class Student:
    def __setattr__(self,name,value):
        if name == "password":
            raise ValueError("禁止添加 'password' 变量!")

        super().__setattr__(name,value)
        
stu1 = Student()
stu1.name = "bob"
stu1.password = "123456" # 报错:ValueError: 禁止添加 'password' 变量!

3.Python中的方法

方法是在类中定义的,这是它们称为方法的根本原因,每次通过类的实例调用方法时,都会传递一个隐藏参数self,它是对实例对象本身的引用。

方法的定义中第一个参数self在方法调用时被隐藏了,因此在方法定义时需要多写一个参数

class Pretty:
    def __init__(self,prefix):
        self.prefix = prefix
    def print_me(self,v1,v2,v3):
        print(self.prefix,v1,sep='')
        print(self.prefix,v2,sep='')
        print(self.prefix,v3,sep='')
        
printer = Pretty('-->')
printer.print_me(10,20,30)

4.封装

核心思想:

  • 就是把类的属性和方法封装类的内部,只能在内部使用,不能在类的外部使用
  • 把属性名和方法名前面加两下划线,这个属性和方法就成为了类的私有属性和方法

作用:

  • 保护数据安全:防止外部随意修改内部的数据
  • 隐藏实现细节:外部只需关注"如何使用",无需了解"内部如何实现"
class Student:
    def __init__(self,name):
        self.name = name
        self.__weight = 199 # __weigth是一个私有属性
    
    def __printer(self):    #__printer方法为私有方法
        print(f"My name is {self.name}")
        
stu = Student("bob")
print(stu.name)
#print(stu.__weight) 不能在类的外部访问类的私有属性  
#stu.__printer()      不能在类的外部调用私有方法

5.继承

核心思想:

  • 让一个类可以继承另一个类的属性和方法,继承的类称为子类,被继承的类称为父类
  • 子类可以新增自己的属性和方法或者重写父类的方法

作用:

  • 代码复用: 避免重复编写相同的代码,子类直接继承父类的功能

实现方式:

  • 定义子类时,在类名后加括号指定父类,如class 子类名(父类名)
#父类 (基类)
class Animal:
    def __init__(self,name):
        self.name = name
    
    def eat(self):
        print(f"{self.name} 在吃东西")
    
#子类 继承Animal
class Dog(Animal):
  	#新增子类独有的方法
    def bark(self):
        print(f"{self.name} 在汪汪叫")
    
    #重写父类的方法
    def eat(self):
        print(f"{self.name}在吃狗粮")

Dog1 = Dog("xiaobai")
Dog1.bark()	# 调用重写后的方法 xiaobai 在汪汪叫
Dog1.eat()	# 调用子类新增方法

6.多态

核心思想:

  • 不同的子类,调用相同的父类的方法,产生不同的结果
  • 不同的子类继承同一个父类时,子类重写父类中定义的方法,从而代替父类方法的实现
class Animal:
    def __init__(self,name):
        self.name = name
    def food(self):
        pass
    def eat(self):
        self.food()

class Dog(Animal):
    def food(self):
        print(f"{self.name}吃肉")

class Cattle(Animal):
    def food(self):
        print(f"{self.name}吃草")

d = Dog("小狗")
c = Cattle("小羊")
d.food()    #小狗吃肉
c.food()    #小羊吃草  

7.类属性和类方法

类属性的定义:

  • 类属性是定义在类内部、方法外部的属性,类属性定义不需要self关键字(self通常用于实例属性,关联到类的具体实例)

类属性的使用:

  • 类属性不需要将类实例化为对象,直接通过类名.属性名的方式来访问和修改
class Animal:
    name = "旺财"   #这就是类属性,定义在类里、方法之外
    def __init__(self):
        pass
print(Animal.name)  #输出:旺财

类属性与实例属性的区别:

  • 类属性:属于类本身,所有类的实例都共享这个属性,如果通过修改类属性,所有实例访问到的该类属性都会改变
  • 实例属性:属于类的某个具体实例,每个实例的实例属性互相独立

类方法定义:

类方法是绑定到类本身而不是类的实例方法,它可以访问和修改类的状态,而无需创建类的实例

类方法的特点:

1.使用@classmethod装饰器定义

2.第一个参数通常是cls,表示类本身(类似实例方法的self)

3.可以通过类名或实例调用

4.不能直接访问实例属性,但可以访问类属性

类方法的使用场景:

  • 用于创建类的备选构造方法
  • 用于操作类属性
  • 当方法需要与类本身交互而不是与实例交互时
class Animal:
    #类属性
    feature = "need food"
    count = 0 #记录创建的实例数量
    
    def __init__(self,name, age):
        self.name = name
        self.age = age
        Animal.count += 1 #每次创建实例,计数器加一
    
    # 实例方法
    def get_name(self):
        return self.name
    
    #类方法, 访问类属性
    @classmethod
    def get_feature(cls):
        return cls.feature
    
    # 类方法 - 修改类属性
    @classmethod
    def edit_feature(cls,new_feature):
        cls.feature = new_feature
        
    # 类方法 - 作为备选构造方法
    @classmethod
    def alternative_method(cls,name,age):
        return cls(name,age)
    
animal1 = Animal("cat",10)
animal2 = Animal("dog",15)
#使用类方法
print(f"通过类名调用类方法:{Animal.get_feature()}")
#通过实例调用类方法
print(f"通过实例调用类方法:{animal1.get_feature()}")
# 修改类属性
Animal.edit_feature("eat food")
print(f"修改后的特征:{Animal.get_feature()}")
#使用备选构造方法
animal3 = Animal.alternative_method("cattle",20)
print(f"{animal3.name}的年龄是:{animal3.age}")
print(f"创建实例的个数是:{Animal.count}")   #3

8.静态方法

在Python中,静态方法可以直接通过类名调用,也可以通过实例调用,但它不会自动接收selfcls参数

静态方法的特点:

1.使用staticmethod装饰器定义

2.无法访问类属性或实例属性

3.调用方式: 类名.方法名()实例名.方法名()

使用场景:

  • 方法不需要访问类或任何实例属性
  • 作为工具函数,与类相关但不需要类数据
class MathUtils:
    #静态方法:计算两个数的和
    @staticmethod
    def add(a,b):
        return a+b
    # 静态方法:计算两个数的乘积
    def multiply(a,b):
        return a*b

#调用静态方法
print(MathUtils.add(1,2))
print(MathUtils.multiply(2,3))

#通过实例调用
math_instance = MathUtils()
print(math_instance.add(2,3))