首页 > 编程语言 >第9篇:从入门到精通:深入理解Python中的类与对象

第9篇:从入门到精通:深入理解Python中的类与对象

时间:2025-01-19 09:03:46浏览次数:3  
标签:__ 精通 入门 Python self 实例 print def 属性

第9篇:类与对象

内容简介

本篇文章将深入探讨Python中的类与对象概念。您将学习如何定义类、创建对象,理解属性与方法的区别与用法,掌握构造函数的使用,以及了解self关键字的作用。通过丰富的代码示例,您将能够熟练运用面向对象编程(OOP)在Python中的核心概念,提升您的编程能力和代码组织水平。


目录

  1. 类与对象概述
    • 什么是类与对象
    • 面向对象编程的优势
  2. 定义类与创建对象
    • 类的基本结构
    • 创建对象实例
  3. 属性与方法
    • 类属性与实例属性
    • 方法的定义与调用
  4. 构造函数 __init__
    • 构造函数的作用
    • 构造函数的参数
  5. self 关键字
    • self 的含义与作用
    • self 在方法中的使用
  6. 示例代码
    • 定义一个简单的类
    • 类属性与实例属性示例
    • 使用构造函数初始化对象
    • self 关键字的实际应用
  7. 常见问题及解决方法
    • 问题1:如何实现继承?
    • 问题2:如何使用多态?
    • 问题3:什么是私有属性与方法?
    • 问题4:如何重载方法?
  8. 总结

类与对象概述

什么是类与对象

**类(Class)**是面向对象编程(OOP)的核心概念之一,它可以被看作是创建对象的蓝图或模板。类定义了对象的属性(数据)和方法(功能)。**对象(Object)**是类的实例,通过类创建的具体实体,拥有类所定义的属性和方法。

类似于现实世界中的蓝图,例如汽车的设计图,而对象则是根据蓝图制造出的具体汽车。

面向对象编程的优势

面向对象编程通过将数据和操作数据的方法封装在一起,提高了代码的可重用性、可维护性和扩展性。其主要优势包括:

  • 封装:将数据和方法绑定在一起,隐藏内部实现细节。
  • 继承:通过继承机制,子类可以继承父类的属性和方法,减少重复代码。
  • 多态:允许不同类的对象以相同的方式调用方法,提高代码的灵活性。

定义类与创建对象

类的基本结构

在Python中,使用class关键字定义一个类。类的基本结构如下:

class ClassName:
    # 类属性
    class_attribute = value

    # 构造函数
    def __init__(self, parameters):
        # 实例属性
        self.instance_attribute = value

    # 方法
    def method_name(self, parameters):
        # 方法体
        pass

示例

class Dog:
    species = "Canis familiaris"  # 类属性

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

    def bark(self):
        return f"{self.name} says woof!"

创建对象实例

通过类名调用构造函数,可以创建类的实例(对象)。每个对象都有自己独立的属性值。

示例

# 创建对象实例
dog1 = Dog("Buddy", 3)
dog2 = Dog("Charlie", 5)

# 调用方法
print(dog1.bark())  # 输出: Buddy says woof!
print(dog2.bark())  # 输出: Charlie says woof!

属性与方法

类属性与实例属性

  • 类属性(Class Attributes):属于类的属性,由类的所有实例共享。类属性在类定义时直接定义。

    示例

    class Dog:
        species = "Canis familiaris"  # 类属性
    
        def __init__(self, name, age):
            self.name = name          # 实例属性
            self.age = age            # 实例属性
    
  • 实例属性(Instance Attributes):属于对象的属性,每个对象都有自己独立的实例属性。实例属性通常在构造函数__init__中定义。

    示例

    dog1 = Dog("Buddy", 3)
    dog2 = Dog("Charlie", 5)
    
    print(dog1.name)  # 输出: Buddy
    print(dog2.name)  # 输出: Charlie
    

方法的定义与调用

**方法(Methods)**是类中定义的函数,用于描述对象的行为。方法通常需要至少一个参数self,用于引用调用该方法的对象实例。

示例

class Dog:
    species = "Canis familiaris"

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

    def bark(self):
        return f"{self.name} says woof!"

    def get_age(self):
        return self.age

# 创建对象
dog = Dog("Buddy", 3)

# 调用方法
print(dog.bark())       # 输出: Buddy says woof!
print(dog.get_age())    # 输出: 3

构造函数 __init__

构造函数的作用

构造函数__init__是一个特殊的方法,在创建对象实例时自动调用,用于初始化对象的属性。它允许您在创建对象时传递参数,并为对象的实例属性赋值。

构造函数的参数

构造函数的第一个参数必须是self,它代表创建的对象实例。后续参数可以根据需要定义,用于初始化实例属性。

示例

class Car:
    def __init__(self, brand, model, year):
        self.brand = brand    # 实例属性
        self.model = model    # 实例属性
        self.year = year      # 实例属性

    def description(self):
        return f"{self.year} {self.brand} {self.model}"

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

print(car1.description())  # 输出: 2020 Toyota Corolla
print(car2.description())  # 输出: 2018 Honda Civic

self 关键字

self 的含义与作用

在Python的类方法中,self是一个约定俗成的名字,代表调用该方法的对象实例。通过self,方法可以访问和修改对象的属性,以及调用其他方法。

self 在方法中的使用

self使得方法能够引用对象自身的属性和其他方法,是实现封装和对象之间交互的关键。

示例

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

    def perimeter(self):
        return 2 * (self.width + self.height)

    def resize(self, new_width, new_height):
        self.width = new_width
        self.height = new_height

# 创建对象实例
rect = Rectangle(4, 5)

# 调用方法
print(rect.area())        # 输出: 20
print(rect.perimeter())   # 输出: 18

# 修改属性
rect.resize(6, 7)
print(rect.area())        # 输出: 42
print(rect.perimeter())   # 输出: 26

示例代码

定义一个简单的类

以下示例展示了如何定义一个简单的Person类,包括属性和方法。

class Person:
    # 类属性
    species = "Homo sapiens"

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

    # 方法
    def greet(self):
        return f"Hello, my name is {self.name} and I am {self.age} years old."

# 创建对象实例
person1 = Person("Alice", 30)
person2 = Person("Bob", 25)

# 调用方法
print(person1.greet())  # 输出: Hello, my name is Alice and I am 30 years old.
print(person2.greet())  # 输出: Hello, my name is Bob and I am 25 years old.

类属性与实例属性示例

以下示例展示了类属性和实例属性的区别与用法。

class Car:
    # 类属性
    wheels = 4

    def __init__(self, brand, model):
        self.brand = brand    # 实例属性
        self.model = model    # 实例属性

# 创建对象实例
car1 = Car("Toyota", "Camry")
car2 = Car("Honda", "Accord")

# 访问类属性
print(Car.wheels)        # 输出: 4
print(car1.wheels)       # 输出: 4
print(car2.wheels)       # 输出: 4

# 修改类属性
Car.wheels = 6
print(car1.wheels)       # 输出: 6
print(car2.wheels)       # 输出: 6

# 修改实例属性
car1.brand = "Ford"
print(car1.brand)        # 输出: Ford
print(car2.brand)        # 输出: Honda

使用构造函数初始化对象

以下示例展示了如何使用构造函数__init__初始化对象的属性。

class Book:
    def __init__(self, title, author, year):
        self.title = title      # 实例属性
        self.author = author    # 实例属性
        self.year = year        # 实例属性

    def description(self):
        return f"'{self.title}' by {self.author}, published in {self.year}."

# 创建对象实例
book1 = Book("1984", "George Orwell", 1949)
book2 = Book("To Kill a Mockingbird", "Harper Lee", 1960)

# 调用方法
print(book1.description())  # 输出: '1984' by George Orwell, published in 1949.
print(book2.description())  # 输出: 'To Kill a Mockingbird' by Harper Lee, published in 1960.

self 关键字的实际应用

以下示例展示了self关键字在类方法中的实际应用,包括访问和修改对象属性。

class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner          # 实例属性
        self.balance = balance      # 实例属性

    def deposit(self, amount):
        self.balance += amount
        return f"Deposited {amount}. New balance: {self.balance}."

    def withdraw(self, amount):
        if amount > self.balance:
            return "Insufficient funds."
        self.balance -= amount
        return f"Withdrew {amount}. New balance: {self.balance}."

# 创建对象实例
account = BankAccount("John Doe")

# 调用方法
print(account.deposit(500))    # 输出: Deposited 500. New balance: 500.
print(account.withdraw(200))   # 输出: Withdrew 200. New balance: 300.
print(account.withdraw(400))   # 输出: Insufficient funds.

常见问题及解决方法

问题1:如何实现继承?

原因:在面向对象编程中,继承允许一个类(子类)继承另一个类(父类)的属性和方法,从而实现代码的重用和扩展。

解决方法

在Python中,通过在类定义时括号中指定父类,实现继承。子类可以重写父类的方法,也可以添加新的属性和方法。

示例

# 父类
class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        return "Some sound"

# 子类
class Dog(Animal):
    def speak(self):
        return "Woof!"

class Cat(Animal):
    def speak(self):
        return "Meow!"

# 创建对象实例
dog = Dog("Buddy")
cat = Cat("Whiskers")

print(dog.name)      # 输出: Buddy
print(dog.speak())   # 输出: Woof!
print(cat.name)      # 输出: Whiskers
print(cat.speak())   # 输出: Meow!

问题2:如何使用多态?

原因:多态允许不同类的对象以相同的方式调用方法,提高代码的灵活性和可扩展性。

解决方法

通过定义一个共同的方法名,不同的子类实现各自的版本,实现多态。

示例

class Shape:
    def area(self):
        pass

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.1416 * self.radius ** 2

# 多态示例
shapes = [
    Rectangle(4, 5),
    Circle(3)
]

for shape in shapes:
    print(f"Area: {shape.area()}")

输出

Area: 20
Area: 28.2744

问题3:什么是私有属性与方法?

原因:私有属性和方法用于封装,防止外部直接访问或修改对象的内部状态,提高代码的安全性和稳定性。

解决方法

在属性和方法名前加双下划线(__),Python会进行名称重整(Name Mangling),使其难以在类外部访问。

示例

class Secret:
    def __init__(self, data):
        self.__data = data    # 私有属性

    def __private_method(self):
        return "This is a private method."

    def public_method(self):
        return f"Accessing private data: {self.__data}"

# 创建对象实例
secret = Secret("Top Secret")

# 访问私有属性(会失败)
# print(secret.__data)  # AttributeError

# 正确访问私有属性通过公共方法
print(secret.public_method())  # 输出: Accessing private data: Top Secret

# 访问私有方法(会失败)
# print(secret.__private_method())  # AttributeError

# 正确访问私有方法通过公共方法
class Secret:
    def __init__(self, data):
        self.__data = data    # 私有属性

    def __private_method(self):
        return "This is a private method."

    def public_method(self):
        return f"Accessing private data: {self.__data}"

    def call_private_method(self):
        return self.__private_method()

secret = Secret("Top Secret")
print(secret.call_private_method())  # 输出: This is a private method.

问题4:如何重载方法?

原因:方法重载允许在同一个类中定义多个方法名相同但参数不同的方法,以适应不同的调用需求。

解决方法

Python不支持传统意义上的方法重载。可以通过默认参数或可变参数实现类似的功能。

示例

class MathOperations:
    def add(self, a, b, c=0):
        return a + b + c

# 创建对象实例
math = MathOperations()

print(math.add(2, 3))      # 输出: 5
print(math.add(2, 3, 4))   # 输出: 9

或者使用可变参数:

class MathOperations:
    def add(self, *args):
        return sum(args)

# 创建对象实例
math = MathOperations()

print(math.add(2, 3))          # 输出: 5
print(math.add(2, 3, 4, 5))    # 输出: 14

示例代码

定义一个简单的类

以下示例展示了如何定义一个简单的Person类,包括属性和方法。

class Person:
    # 类属性
    species = "Homo sapiens"

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

    # 方法
    def greet(self):
        return f"Hello, my name is {self.name} and I am {self.age} years old."

# 创建对象实例
person1 = Person("Alice", 30)
person2 = Person("Bob", 25)

# 调用方法
print(person1.greet())  # 输出: Hello, my name is Alice and I am 30 years old.
print(person2.greet())  # 输出: Hello, my name is Bob and I am 25 years old.

类属性与实例属性示例

以下示例展示了类属性和实例属性的区别与用法。

class Car:
    # 类属性
    wheels = 4

    def __init__(self, brand, model):
        self.brand = brand    # 实例属性
        self.model = model    # 实例属性

# 创建对象实例
car1 = Car("Toyota", "Camry")
car2 = Car("Honda", "Accord")

# 访问类属性
print(Car.wheels)        # 输出: 4
print(car1.wheels)       # 输出: 4
print(car2.wheels)       # 输出: 4

# 修改类属性
Car.wheels = 6
print(car1.wheels)       # 输出: 6
print(car2.wheels)       # 输出: 6

# 修改实例属性
car1.brand = "Ford"
print(car1.brand)        # 输出: Ford
print(car2.brand)        # 输出: Honda

使用构造函数初始化对象

以下示例展示了如何使用构造函数__init__初始化对象的属性。

class Book:
    def __init__(self, title, author, year):
        self.title = title      # 实例属性
        self.author = author    # 实例属性
        self.year = year        # 实例属性

    def description(self):
        return f"'{self.title}' by {self.author}, published in {self.year}."

# 创建对象实例
book1 = Book("1984", "George Orwell", 1949)
book2 = Book("To Kill a Mockingbird", "Harper Lee", 1960)

# 调用方法
print(book1.description())  # 输出: '1984' by George Orwell, published in 1949.
print(book2.description())  # 输出: 'To Kill a Mockingbird' by Harper Lee, published in 1960.

self 关键字的实际应用

以下示例展示了self关键字在类方法中的实际应用,包括访问和修改对象属性。

class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner          # 实例属性
        self.balance = balance      # 实例属性

    def deposit(self, amount):
        self.balance += amount
        return f"Deposited {amount}. New balance: {self.balance}."

    def withdraw(self, amount):
        if amount > self.balance:
            return "Insufficient funds."
        self.balance -= amount
        return f"Withdrew {amount}. New balance: {self.balance}."

# 创建对象实例
account = BankAccount("John Doe")

# 调用方法
print(account.deposit(500))    # 输出: Deposited 500. New balance: 500.
print(account.withdraw(200))   # 输出: Withdrew 200. New balance: 300.
print(account.withdraw(400))   # 输出: Insufficient funds.

常见问题及解决方法

问题1:如何实现继承?

原因:在面向对象编程中,继承允许一个类(子类)继承另一个类(父类)的属性和方法,从而实现代码的重用和扩展。

解决方法

在Python中,通过在类定义时括号中指定父类,实现继承。子类可以重写父类的方法,也可以添加新的属性和方法。

示例

# 父类
class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        return "Some sound"

# 子类
class Dog(Animal):
    def speak(self):
        return "Woof!"

class Cat(Animal):
    def speak(self):
        return "Meow!"

# 创建对象实例
dog = Dog("Buddy")
cat = Cat("Whiskers")

print(dog.name)      # 输出: Buddy
print(dog.speak())   # 输出: Woof!
print(cat.name)      # 输出: Whiskers
print(cat.speak())   # 输出: Meow!

问题2:如何使用多态?

原因:多态允许不同类的对象以相同的方式调用方法,提高代码的灵活性和可扩展性。

解决方法

通过定义一个共同的方法名,不同的子类实现各自的版本,实现多态。

示例

class Shape:
    def area(self):
        pass

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.1416 * self.radius ** 2

# 多态示例
shapes = [
    Rectangle(4, 5),
    Circle(3)
]

for shape in shapes:
    print(f"Area: {shape.area()}")

输出

Area: 20
Area: 28.2744

问题3:什么是私有属性与方法?

原因:私有属性和方法用于封装,防止外部直接访问或修改对象的内部状态,提高代码的安全性和稳定性。

解决方法

在属性和方法名前加双下划线(__),Python会进行名称重整(Name Mangling),使其难以在类外部访问。

示例

class Secret:
    def __init__(self, data):
        self.__data = data    # 私有属性

    def __private_method(self):
        return "This is a private method."

    def public_method(self):
        return f"Accessing private data: {self.__data}"

# 创建对象实例
secret = Secret("Top Secret")

# 访问私有属性(会失败)
# print(secret.__data)  # AttributeError

# 正确访问私有属性通过公共方法
print(secret.public_method())  # 输出: Accessing private data: Top Secret

# 访问私有方法(会失败)
# print(secret.__private_method())  # AttributeError

# 正确访问私有方法通过公共方法
class Secret:
    def __init__(self, data):
        self.__data = data    # 私有属性

    def __private_method(self):
        return "This is a private method."

    def public_method(self):
        return f"Accessing private data: {self.__data}"

    def call_private_method(self):
        return self.__private_method()

secret = Secret("Top Secret")
print(secret.call_private_method())  # 输出: This is a private method.

问题4:如何重载方法?

原因:方法重载允许在同一个类中定义多个方法名相同但参数不同的方法,以适应不同的调用需求。

解决方法

Python不支持传统意义上的方法重载。可以通过默认参数或可变参数实现类似的功能。

示例

class MathOperations:
    def add(self, a, b, c=0):
        return a + b + c

# 创建对象实例
math = MathOperations()

print(math.add(2, 3))      # 输出: 5
print(math.add(2, 3, 4))   # 输出: 9

或者使用可变参数:

class MathOperations:
    def add(self, *args):
        return sum(args)

# 创建对象实例
math = MathOperations()

print(math.add(2, 3))          # 输出: 5
print(math.add(2, 3, 4, 5))    # 输出: 14

总结

在本篇文章中,我们深入探讨了Python中的类与对象。通过理解类与对象的基本概念,学习如何定义类、创建对象,掌握属性与方法的区别与用法,了解构造函数__init__的作用,以及熟练使用self关键字,您已经具备了面向对象编程的基础知识。面向对象编程不仅能帮助您编写更清晰、更可维护的代码,还能提升代码的复用性和扩展性。

学习建议

  1. 实践OOP项目:通过实际项目,如开发简单的游戏、管理系统等,巩固所学知识。
  2. 深入学习继承与多态:理解更复杂的继承关系和多态应用,提升代码的灵活性。
  3. 探索高级OOP概念:如抽象类、接口、装饰器等,扩展您的编程技能。
  4. 优化代码设计:学习设计模式(如单例模式、工厂模式、观察者模式),提高代码的设计质量。
  5. 编写文档与测试:为类和方法编写清晰的文档和单元测试,确保代码的可靠性和可维护性。
  6. 参与社区与开源项目:通过参与开源项目,学习他人的代码风格和最佳实践,提升编程能力。
  7. 阅读相关书籍和文档:如《Python编程:从入门到实践》、《面向对象编程与设计模式》,系统性地提升OOP能力。

接下来的系列文章将继续深入探讨Python的异常处理与调试技巧,帮助您进一步掌握Python编程的核心概念和技巧。保持学习的热情,持续实践,您将逐步成为一名优秀的Python开发者!


如果您有任何问题或需要进一步的帮助,请随时在评论区留言或联系相关技术社区。

标签:__,精通,入门,Python,self,实例,print,def,属性
From: https://blog.csdn.net/martian665/article/details/145063420

相关文章

  • 第10篇:从入门到精通:深入理解Python继承与多态的概念及应用
    第10篇:继承与多态内容简介本篇文章将深入探讨Python中的继承与多态概念。您将学习如何通过类的继承实现代码的重用,掌握方法重写的技巧,了解如何使用super()函数调用父类的方法,并探索多态的实现与应用。通过丰富的代码示例,您将能够熟练运用继承与多态,提升您的面向对象编程(OO......
  • python-45-python代码的加速运行优化方式
    文章目录1基础策略和原则1.1常见的优化策略1.2基本的优化原则1.3避免全局变量2避免模块和函数属性访问2.1不推荐写法【32s】2.2消除属性访问(优化1)【28s】2.3局部变量加速(优化2)【24s】2.4局部继续加速(优化3)【22s】2.5减少内层for循环计算......
  • 使用PythonDEAP库实现简单遗传算法
    ​本人博客食用体验更佳哦DEAP(DistributedEvolutionaryAlgorithmsinPython)是一个用于快速原型设计和实验的进化计算框架。它支持多种进化算法,包括遗传算法、遗传编程、进化策略、粒子群优化等。DEAP的设计目标是灵活性和易用性,使得研究人员和开发者能够轻松地实现和测试各......
  • Redis 入门教程:什么是 Redis?如何开始使用?
    Redis入门教程:什么是Redis?如何开始使用?Redis是一个开源的内存数据结构存储系统,广泛用于缓存、消息队列、实时数据处理等场景。它不仅速度快,而且支持多种数据结构(如字符串、哈希、列表、集合等),因此非常适合处理大量实时数据。今天,我们将带你一起快速了解Redis,并教你如何上......
  • python-leetcode-存在重复元素 II
    219.存在重复元素II-力扣(LeetCode)classSolution:defcontainsNearbyDuplicate(self,nums:List[int],k:int)->bool:seen=set()fori,numinenumerate(nums):ifnuminseen:returnTrue......
  • python-leetcode-最小覆盖子串
    76.最小覆盖子串-力扣(LeetCode)classSolution:defminWindow(self,s:str,t:str)->str:ifnotsornott:return""need={}forcint:need[c]=need.get(c,0)+1windo......
  • 用Python检查Android字符串文件通配符
    #!/usr/bin/envpython3importosimportsysfromdatetimeimportdatetime,timedeltaimportreimportxml.etree.ElementTreeasETiflen(sys.argv)<3:exit()print(datetime.now(),'start')timestamp=int(datetime.now().timestamp())en_t......
  • 电子工程师入门-03三极管详解(上)
    以下内容均作为个人学习时遇到问题的学习历程,记在这里也是希望自己能常回顾。另外,文章出现的图片有些是个人手绘不太标准。前言:三极管是流控型器件。一,三极管初识晶体三极管中有两种带有不同极性电荷的载流子参与导电,因此称之为双极性晶体管(BJT),又称半导体三极管。根据不同......
  • Linux基础-指令篇02【入门级】
    内容提要本章对文件系统以及目录操作进行了讲解,主要包括利用指令对文件/目录进行增删改查的操作。文件系统Linux本质上就是一个文件系统,Linux文件系统是操作系统组织存取、保存数据的一种手段。整体采用层级式的倒状树倒状树结构中的目录/:根目录,Linux中的绝对路径由此......
  • java零基础入门(一)
    Java零基础入门(一)一Java版本Java共分为三个版本JavaSE标准版最为基础的版本适合桌面程序、控制台开发等等JavaME嵌入式开发适合小家电等目前基本上已不再使用JavaEE企业级开发适用于web端、服务器开发等二Java安装环境介绍以下三个概念为下层包含上层的关系......