Python中的类和对象

一、类和对象的基本概念

1. 类(Class)

  • 定义:类是一个代码模板,用于定义一组具有相同属性和方法的对象。
  • 作用:类就像一个模板,描述了对象的结构和行为。

2. 对象(Object)

  • 定义:对象是类的一个实例,是具体的实体。
  • 作用:对象是根据类创建的,可以调用类中的方法和访问类中的属性。

二、定义类

1. 基本语法

class 类名:
    #  初始化方法
    def __init__(self, 参数1, 参数2, ...):  
        self.属性1 = 参数1
        self.属性2 = 参数2
        # 初始化对象的属性

    def 方法1(self):
        # 方法1的实现

    def 方法2(self):
        # 方法2的实现

规则

  • 类名首字母大写。
  • 使用 class 关键字定义类。
  • 类中可以包含属性和方法。
  • 构造方法 __init__ 用于初始化对象的属性。

2. 示例:定义一个 Person

class Person:
    def __init__(self, name, age):  # 构造方法
        self.name = name  # 属性:名字
        self.age = age    # 属性:年龄

    def say_hello(self):  # 方法:打招呼
        print(f"Hello, my name is {self.name} and I am {self.age} years old.")

    def celebrate_birthday(self):  # 方法:庆祝生日
        self.age += 1
        print(f"Happy Birthday! I am now {self.age} years old.")

三、创建对象

1. 基本语法

对象名 = 类名(参数1, 参数2, ...)

2. 示例:创建 Person 对象

# 创建一个 Person 对象
person1 = Person("Alice", 25)

# 调用对象的方法
person1.say_hello()  # 输出:Hello, my name is Alice and I am 25 years old.

# 访问对象的属性
print(person1.name)  # 输出:Alice
print(person1.age)   # 输出:25

# 修改对象的属性
person1.age = 26
print(person1.age)   # 输出:26

# 调用对象的另一个方法
person1.celebrate_birthday()  # 输出:Happy Birthday! I am now 27 years old.

四、类的组成

4.1 类属性

  • 定义:类属性是定义在类中、方法外的变量,属于类本身。
  • 访问方式:通过类名访问,例如 类名.属性名或者对象.属性名

示例

class Student:
    school = 'newday.edu'  # 类属性

    def __init__(self, name, age):
        self.name = name
        self.age = age

# 访问类属性
print(Student.school)  # 输出:newday.edu

stu = Student('kyle',20)
print(stu.school)      # # 输出:newday.edu

4.2 实例属性

  • 定义:实例属性是通过 self 关键字定义的,属于对象本身。
  • 访问方式:通过对象名访问,例如 对象名.属性名

示例

class Student:
    school = 'newday.edu'  # 类属性

    def __init__(self, name, age):
        self.name = name  # 实例属性
        self.age = age    # 实例属性

# 创建对象
stu = Student('kyle', 20)

# 访问实例属性
print(stu.name)  # 输出:kyle
print(stu.age)   # 输出:20

4.3 实例方法

  • 定义:实例方法是定义在类中的函数,第一个参数必须是 self,表示对象本身。
  • 调用方式:通过对象名调用,例如 对象名.方法名()

示例

class Student:
    school = 'newday.edu'

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def show(self):  # 实例方法
        print(f'我叫:{self.name}, 我今年{self.age}岁了')

# 创建对象
stu = Student('kyle', 20)

# 调用实例方法
stu.show()  # 输出:我叫:kyle, 我今年20岁了

4.4 类方法

  • 定义:类方法通过 @classmethod 装饰器定义,第一个参数是 cls,表示类本身。
  • 调用方式:通过类名调用,例如 类名.方法名()

示例

class Student:
    school = 'newday.edu'

    @classmethod
    def cm(cls):  # 类方法
        print('这是一个类方法,不能调用实例属性,也不能调用实例方法')

# 调用类方法
Student.cm()  # 输出:这是一个类方法,不能调用实例属性,也不能调用实例方法

4.5 静态方法

  • 定义:静态方法通过 @staticmethod 装饰器定义,不需要 selfcls 参数。
  • 调用方式:通过类名调用,例如 类名.方法名()

示例

class Student:
    school = 'newday.edu'

    @staticmethod
    def sm():  # 静态方法
        print('这是一个静态方法,不能调用实例属性,也不能调用实例方法')

# 调用静态方法
Student.sm()  # 输出:这是一个静态方法,不能调用实例属性,也不能调用实例方法

4.6 综合示例:定义一个Student

class Student:
    #类属性:定义在类中,方法外的变量
    school='newday.edu'

    #初始化方法
    def __init__(self,xm,age): #xm,age 是方法的参数,是局部变量,xm,age的作用域是整个__init__方法
        # 定义类的实例属性
        self.name=xm  # 左侧是实例属性,xm是局部变量将局部变量的值xm赋给实例属性self.name
        self.age=age  # 实例属性的名称可以和局部变量一致
    # 定义在类中的函数,称为方法,自带一个参数self
    def show(self):
        print(f'我叫:{self.name},我今年{self.age}岁了')

    # 静态方法
    @staticmethod
    def sm():
        # print(self.name) #报错
        # self.show()  # 报错
        print('这是一个静态方法,不能调用实例属性,也不能调用实例方法')

    # 类方法
    @classmethod
    def cm(cls):  # cls-->class的简写
        # print(self.name) #报错
        # self.show()  # 报错
        print('这是一个类方法,不能调用实例属性,也不能调用实例方法')

# 创建类的对象
stu=Student('kyle',20) # 为什么传了两个参数,因为__int__方法中,偶两个形参,self,是自带的参数,无需手动传入
# 实例属性,使用对象名进行打点掉用的
print(stu.name,stu.age)
# 类属性,直接使用类名,打点调用
print(Student.school)

# 实例方法,使用对象名进行打点调用
stu.show()

# 类方法, @classmethod 进行修饰的方法,直接使用类名进行打点调用
Student.cm()
# 静态方法 @staticmethod进行修饰的方法,直接使用类名进行打点调用
Student.sm()

4.7 综合示例:定义一个Car

class Car:
    # 类属性
    total_cars = 0  # 用于记录创建的汽车总数

    def __init__(self, make, model, year):  # 构造方法
        """
        初始化Car类的实例。
        :param make: 汽车制造商
        :param model: 汽车型号
        :param year: 汽车制造年份
        """
        self.make = make  # 实例属性:制造商
        self.model = model  # 实例属性:型号
        self.year = year  # 实例属性:年份
        self._odometer = 0  # 私有属性:里程表
        Car.total_cars += 1  # 更新类属性

    def get_description(self):  # 实例方法
        """
        返回汽车的详细描述。
        """
        return f"{self.year} {self.make} {self.model}"

    def read_odometer(self):  # 实例方法
        """
        打印汽车的里程。
        """
        print(f"This car has {self._odometer} miles on it.")

    def update_odometer(self, mileage):  # 实例方法
        """
        更新汽车的里程。
        :param mileage: 新的里程数
        """
        if mileage >= self._odometer:
            self._odometer = mileage
        else:
            print("You can't roll back an odometer!")

    @classmethod
    def get_total_cars(cls):  # 类方法
        """
        返回创建的汽车总数。
        """
        return cls.total_cars

    @staticmethod
    def is_valid_year(year):  # 静态方法
        """
        检查年份是否有效。
        :param year: 年份
        :return: 是否是有效年份
        """
        return 1900 <= year <= 2025

类的组成部分解释

  1. 类名Car,标识这个类。
  2. 构造方法__init__方法,用于初始化对象的属性。每次创建对象时都会调用。
  3. 实例属性
    • self.make:汽车制造商。
    • self.model:汽车型号。
    • self.year:汽车制造年份。
    • self._odometer:私有属性,表示汽车的里程表。
  4. 实例方法
    • get_description:返回汽车的详细描述。
    • read_odometer:打印汽车的里程。
    • update_odometer:更新汽车的里程。
  5. 类属性
    • total_cars:记录创建的汽车总数。
  6. 类方法
    • get_total_cars:返回创建的汽车总数。通过cls访问类属性。
  7. 静态方法
    • is_valid_year:检查年份是否有效。不依赖于类或实例属性。

使用类和对象

# 创建Car对象
car1 = Car("Toyota", "Corolla", 2020)
car2 = Car("Honda", "Civic", 2018)

# 调用实例方法
print(car1.get_description())  # 输出:2020 Toyota Corolla
car1.read_odometer()  # 输出:This car has 0 miles on it.
car1.update_odometer(100)
car1.read_odometer()  # 输出:This car has 100 miles on it.

# 调用类方法
print(Car.get_total_cars())  # 输出:2

# 调用静态方法
print(Car.is_valid_year(2020))  # 输出:True
print(Car.is_valid_year(1800))  # 输出:False

总结

类的组成包括类名、构造方法、属性、方法、类方法、静态方法和私有属性/方法。这些组成部分共同定义了类的结构和行为,使得类可以用于创建具有相同特征和行为的对象。


五、对象的动态属性和方法

可以为某个对象动态绑定独有的属性或方法。

示例

class Student:
    school = 'newday.edu'

    def __init__(self, name, age):
        self.name = name
        self.age = age

# 创建对象
stu1 = Student('kyle', 20)
stu2 = Student('Ming', 21)

# 动态绑定属性
stu1.gender = 'Male'
print(stu1.gender)  # 输出:Male
# print(stu2.gender)  # 报错,因为 stu2 没有 gender 属性

# 动态绑定方法
def introduce():
  print("动态绑定方法")
stu1.fun = introduce  # 不可以加小括号,加小括号为调用,这里是函数赋值绑定
stu1.fun()   # 动态绑定方法
# stu2.fun() # AttributeError: 'Student' object has no attribute 'fun',因为 stu2 没有 fun 方法

六、私有属性和方法

1. 私有属性

  • 在类中,以双下划线__开头的属性是私有属性,不能直接从类外部访问。
  • 示例:
class Person:
    def __init__(self, name, age):
        self.__name = name  # 私有属性
        self.age = age

    def get_name(self):  # 提供一个方法来访问私有属性
        return self.__name
  • 使用:
person = Person("Alice", 25)
print(person.age)  # 可以直接访问
# print(person.__name)  # 会报错,因为__name是私有属性
print(person.get_name())  # 输出:Alice

2. 私有方法

  • 在类中,以双下划线__开头的方法是私有方法,不能直接从类外部调用。
  • 示例:
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __private_method(self):  # 私有方法
        print("This is a private method.")

    def public_method(self):  # 公共方法
        self.__private_method()  # 在类内部调用私有方法
  • 使用:
person = Person("Alice", 25)
person.public_method()  # 输出:This is a private method.
# person.__private_method()  # 会报错,因为__private_method是私有方法

七、多个对象的管理

可以将多个对象存储到列表中,方便统一管理。

示例

class Student:
    school = 'newday.edu'

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def show(self):
        print(f'我叫:{self.name}, 我今年{self.age}岁了')

# 创建多个对象
stu1 = Student('kyle', 20)
stu2 = Student('Ming', 21)
stu3 = Student('Ting', 18)
stu4 = Student('Ying', 23)

# 将对象存储到列表中
students = [stu1, stu2, stu3, stu4]

# 遍历列表并调用方法
for student in students:
    student.show()

-------------------------------------------
结果:
  我叫:kyle, 我今年20岁了
  我叫:Ming, 我今年21岁了
  我叫:Ting, 我今年18岁了
  我叫:Ying, 我今年23岁了

八、类和对象的总结

  • 类属性类方法静态方法 都是通过类名调用的。
  • 实例属性实例方法 是通过对象调用的。
  • 类属性属于类本身,所有对象共享;实例属性属于对象本身,每个对象独立。
  • 私有属性和方法:保护类的内部实现细节,防止外部直接访问。- 私有属性和方法:保护类的内部实现细节,防止外部直接访问。

九、object 类简介

object 类是 Python 中所有类的基类,无论是直接还是间接继承,所有类都源自 object 类。因此,所有类都继承了 object 类的属性和方法。

1. object 类中的特殊方法

方法 功能描述
__new__() 由系统调用,用于创建对象。通常用于自定义对象的创建过程。
__init__() 创建对象时手动调用,用于初始化对象的属性值。
__str__() 返回对象的描述,返回值是 str 类型。默认输出对象的内存地址,可通过重写自定义。

2. 示例代码:__init____str__ 的使用

# 定义一个 Person 类
class Person:
    def __init__(self, name, age):
        """
        构造方法,用于初始化对象的属性。
        :param name: str,表示人的名字
        :param age: int,表示人的年龄
        """
        self.name = name
        self.age = age

    def say_hello(self):
        """
        打印问候语。
        """
        print(f'Hello everyone, my name is {self.name}, age {self.age}')

# 创建 Person 类的实例
per = Person('Kyle', 20)  # 创建对象时自动调用 __init__() 方法

# 调用对象的方法
per.say_hello()  # 输出:Hello everyone, my name is Kyle, age 20

# 查看对象的所有属性和方法
print(dir(per))
# 输出:
# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__',
# '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__',
# '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__',
# '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',
# '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
# '__weakref__', 'age', 'name', 'say_hello']

3. 默认的 __str__ 方法

默认情况下,__str__ 方法返回对象的内存地址,例如:

# 直接输出对象名,调用默认的 __str__ 方法
print(per)  # 输出:<__main__.Person object at 0x0000023CF35F1D60>

这种输出形式对于调试和理解对象的内存地址很有用,但对于用户来说不太直观。

4. 自定义 __str__ 方法

可以通过重写 __str__ 方法来自定义对象的字符串表示形式,使其更易于理解和阅读。

# 定义一个 Person 类,并重写 __str__ 方法
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def say_hello(self):
        print(f'Hello everyone, my name is {self.name}, age {self.age}')

    #方法重新
    def __str__(self):   #与默认的__str__()方法名字一致
        """
        自定义对象的字符串表示形式。
        :return: str,描述对象的字符串
        """
        return f'Person(name={self.name}, age={self.age})'

# 创建 Person 类的实例
per = Person('Kyle', 20)

# 直接输出对象名,调用自定义的 __str__ 方法
print(per)  # 输出:Person(name=Kyle, age=20)

# 手动调用 __str__ 方法
print(per.__str__())  # 输出:Person(name=Kyle, age=20)

5. __new__ 方法

__new__ 是一个特殊的静态方法,用于创建对象。它在 __init__ 之前被调用,负责返回一个类的实例。通常用于自定义对象的创建过程。

class Person:
    def __new__(cls, name, age):
        print("Creating a new instance of Person")
        return super(Person, cls).__new__(cls)
            """
            super(Person, cls):调用父类(即 object 类)的 __new__ 方法。
            __new__(cls):创建并返回一个 Person 类的实例。
            这一行代码是必须的,因为如果不调用父类的 __new__ 方法,就不会真正创建出一个对象实例。
            """
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return f'Person(name={self.name}, age={self.age})'

# 创建对象时,会先调用 __new__ 方法
per = Person('Kyle', 20)
print(per)  # 输出:Creating a new instance of Person
            #       Person(name=Kyle, age=20)

6. 总结

  • object 类是 Python 中所有类的基类,所有类都继承了 object 类的属性和方法。

  • __init__ 方法用于初始化对象的属性值,是构造方法。

  • __str__ 方法用于定义对象的字符串表示形式,默认输出对象的内存地址,可以通过重写来自定义输出。

  • __new__ 方法用于创建对象,通常用于自定义对象的创建过程。


posted @ 2025-04-04 20:49  kyle_7Qc  阅读(169)  评论(0)    收藏  举报