面向对象编程(OOP)在Python中的应用

面向对象编程(OOP)在Python中的应用

面向对象编程(Object-Oriented Programming,简称OOP)是一种以对象为核心的编程范式。Python是一种支持多种编程范式的语言,其中对OOP的支持尤为强大和灵活。本文将通过以下几个方面介绍Python中的OOP:

目录

面向对象编程(OOP)在Python中的应用

1. 基本概念

2. 类和对象

3. 继承

4. 多态

5. 封装

6. 面向对象设计的实践准则

7. 面向对象的理解

Object类

1. 基本方法

__init__(self, ...)

__new__(cls, ...)

2. 字符串和表示方法

__str__(self)

__repr__(self)

3. 比较与哈希

__eq__(self, other)

__hash__(self)

4. 内存管理

__del__(self)

__sizeof__(self)

5. 其他通用方法

__getattribute__(self, name)

__setattr__(self, name, value)

__delattr__(self, name)

6. 动态方法

__dir__(self)

系统函数及其对应的类方法(表格)


1. 基本概念

在OOP中,以下几个核心概念需要理解:

  • 类(Class):描述对象的抽象蓝图,包括属性和方法。

  • 对象(Object):类的实例,是类的具体表现形式。

  • 属性(Attribute):类中描述对象特征的变量。

  • 方法(Method):类中定义的函数,表示对象的行为。


2. 类和对象

在Python中,定义类使用class关键字,创建对象通过调用类。

# 定义一个简单的类
class Animal:
    def __init__(self, name, sound):
        self.name = name  # 属性
        self.sound = sound  # 属性

    def make_sound(self):
        # 方法
        return f"{self.name} says {self.sound}"

# 创建对象
cat = Animal("Cat", "Meow")
dog = Animal("Dog", "Woof")

print(cat.make_sound())  # 输出: Cat says Meow
print(dog.make_sound())  # 输出: Dog says Woof
  • __init__是类的构造方法,用于初始化对象。

  • self表示当前实例对象,必须作为方法的第一个参数。


3. 继承

继承允许我们基于现有类创建新类,新的类(子类)可以重用、扩展或修改父类的功能。

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

    def speak(self):
        return "Unknown sound"

# 定义子类
class Dog(Animal):
    def speak(self):
        return f"{self.name} says Woof!"

class Cat(Animal):
    def speak(self):
        return f"{self.name} says Meow!"

# 创建子类实例
dog = Dog("Buddy")
cat = Cat("Kitty")

print(dog.speak())  # 输出: Buddy says Woof!
print(cat.speak())  # 输出: Kitty says Meow!

子类通过继承获得父类的属性和方法,并可以根据需要重写方法。

参考链接:Python 继承详解

优点

  • 代码复用:子类继承了父类的属性和方法,减少了代码冗余。

  • 扩展性强:可以在子类中添加新的属性或重写父类方法,实现功能扩展。

  • 层次结构清晰:通过继承可以建立类与类之间的层次关系,有助于代码的组织和维护。


4. 多态

多态是指同一接口,表现出不同的行为。我们可以在不关心对象具体类型的情况下调用方法。

def animal_sound(animal):
    print(animal.speak())

# 多态示例
animals = [Dog("Buddy"), Cat("Kitty")]
for animal in animals:
    animal_sound(animal)

在上述代码中,无论传入的是Dog还是Catanimal_sound函数都能正确调用speak方法。

优点

  • 接口统一:不同子类可以实现同一个方法,调用时无需关心具体对象的类型,代码更灵活。

  • 扩展性强:可以轻松添加新的子类,而不影响现有代码。

  • 降低耦合:调用者只需关注接口而无需了解具体实现细节,提高代码的可维护性。


5. 封装

封装通过控制属性的访问级别来实现数据保护。Python中通过以下方式实现:

  • 单下划线_:提示属性是保护的,不建议直接访问。

  • 双下划线__:实现属性的私有化。

class BankAccount:
    def __init__(self, balance):
        self.__balance = balance  # 私有属性

    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount

    def withdraw(self, amount):
        if 0 < amount <= self.__balance:
            self.__balance -= amount

    def get_balance(self):
        return self.__balance

account = BankAccount(1000)
account.deposit(500)
account.withdraw(200)
print(account.get_balance())  # 输出: 1300

直接访问__balance会报错,必须通过类提供的方法访问。

优点

  • 数据安全性:通过限制直接访问属性,避免外部代码对属性的不当修改。

  • 操作简化:提供统一的访问方法(getter和setter),方便操作数据。

  • 灵活性高:可以对数据的访问进行更多的控制,比如添加验证逻辑。


6. 面向对象设计的实践准则

  1. 单一职责原则:一个类只负责一个职责。

  2. 开闭原则:类应该对扩展开放,对修改关闭。

  3. 组合优于继承:优先考虑通过组合对象实现功能,而不是通过继承。

  4. 避免过度设计:保持代码简单,避免为未来的需求设计过多抽象。


7. 面向对象的理解

面向对象的核心思想是将现实世界中的事物抽象为对象,并通过对象的属性和方法对其进行操作。简而言之,面向对象就是[对象].[属性/方法]。

如果你不理解,那么请看下列代码

# 1
"hello".split() # "hello"是字符串对象,split()是字符串对象的类方法,他们维护着一个字符串
# 2
s = "hello"
len(s)  # s是一个字符串对象,len()实际上是调用的字符串对象的__len__()方法,如果没有这个方法,那么len(s)会报错:TypeError: object of type 'xx' has no len()

上述代码实际上都是在维护类中的某个属性,为了操纵某个属性而写了众多的类方法,又叫接口,供使用者调用。

实际上,这种设计理念的目标是维护某类属性,使代码更贴近现实逻辑、更易于理解和维护。例如:

car = Car("Toyota", "Corolla")
print(car.brand)  # 属性: 输出品牌
print(car.drive())  # 方法: 调用驾驶行为

从深入的层面理解,面向对象是一种通过分解问题并将解决方案模块化的思考方式。现实世界中的事物通常是复杂的,OOP通过将功能组织到类和对象中,将这些复杂性分解为更小、更可管理的部分。

  1. 抽象世界:面向对象通过类将事物的共性抽象出来,用对象表达具体实例。类是模板,实例是现实。

    • 比如,汽车可以抽象为类,而某辆具体的汽车是该类的一个实例。

  2. 强调状态和行为的结合

    • 状态:对象的属性(比如汽车的品牌、颜色)。

    • 行为:对象的方法(比如启动、驾驶)。

  3. 重视逻辑封装:通过隐藏实现细节并只暴露必要的接口,面向对象确保了代码模块的独立性和安全性。

  4. 自然的模拟:面向对象和人类理解事物的方式一致,易于建模现实世界的问题。

Object类

以下是 object 类主要方法和属性的汇总表:

方法/属性 描述 示例
__init__(self, …) 构造方法,初始化对象。 def __init__(self, name): self.name = name
__new__(cls, …) 创建对象实例,在 __init__ 之前调用。 def __new__(cls, *args): return super().__new__(cls)
__str__(self) 返回对象的“可读”字符串表示,供用户查看。 def __str__(self): return f"MyClass(name={self.name})"
__repr__(self) 返回对象的“官方”字符串表示,供开发者查看。 def __repr__(self): return f"MyClass(name={self.name!r})"
__eq__(self, …) 定义对象的相等性比较 (==)。 def __eq__(self, other): return self.value == other.value
__hash__(self) 返回对象的哈希值,用于字典键或集合元素。 def __hash__(self): return hash(self.value)
__del__(self) 对象被销毁时调用,用于清理资源。 def __del__(self): print("Object deleted")
__sizeof__(self) 返回对象的内存大小(字节)。 def __sizeof__(self): return super().__sizeof__()
__getattribute__() 在访问属性时调用,用于拦截属性访问。 def __getattribute__(self, name): return super().__getattribute__(name)
__setattr__(self) 在设置属性时调用,用于拦截属性赋值。 def __setattr__(self, name, value): super().__setattr__(name, value)
__delattr__(self) 在删除属性时调用,用于拦截属性删除。 def __delattr__(self, name): super().__delattr__(name)
__dir__(self) 自定义 dir() 方法返回的属性列表。 def __dir__(self): return ['custom_attribute']
__format__(self) 定义对象的格式化字符串表示(支持 format() 函数)。 def __format__(self, format_spec): return f"Formatted {self.value}"
__reduce__(self) 提供对象序列化支持(如用于 pickle)。 def __reduce__(self): return (MyClass, (self.value,))
__reduce_ex__() 类似于 __reduce__,但支持扩展协议。 -
__subclasshook__() 用于动态判断类是否是某个抽象基类的子类。 @classmethod def __subclasshook__(cls, subclass): return True if 'method' in dir(subclass) else NotImplemented
__class__ 表示对象所属的类。 obj.__class__
__doc__ 类或方法的文档字符串。 MyClass.__doc__

1. 基本方法

__init__(self, ...)

  • 作用:构造方法,实例化对象时被调用,用于初始化对象的属性。
  • 示例
class MyClass: 
    def __init__(self, name): 
    self.name = name 
obj = MyClass("Alice")

__new__(cls, ...)

  • 作用:用于创建类的实例,在对象实例化之前被调用。它决定是否创建一个新实例。
  • 说明:通常与 __init__ 配合使用,但很少直接重写。
  • 示例
class MyClass:
    def __new__(cls, *args, **kwargs):
        print("Creating instance")
        return super().__new__(cls)

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

obj = MyClass("Alice")

2. 字符串和表示方法

__str__(self)

  • 作用:定义对象的“可读”字符串表示,在 print()str() 时被调用。
  • 示例
    class MyClass:
        def __str__(self):
            return f"MyClass with name {self.name}"
    
        def __init__(self, name):
            self.name = name
    
    obj = MyClass("Alice")
    print(obj)  # 输出:MyClass with name Alice
    

__repr__(self)

  • 作用:定义对象的“官方”字符串表示,通常用于调试或记录。
  • 区别__repr__ 主要是为开发者设计的,__str__ 面向用户。
  • 示例
    class MyClass:
        def __repr__(self):
            return f"MyClass(name={self.name!r})"
    
        def __init__(self, name):
            self.name = name
    
    obj = MyClass("Alice")
    print(repr(obj))  # 输出:MyClass(name='Alice')
    


3. 比较与哈希

__eq__(self, other)

  • 作用:定义对象的相等性比较 (==)。
  • 示例
    class MyClass:
        def __init__(self, value):
            self.value = value
    
        def __eq__(self, other):
            return self.value == other.value
    
    obj1 = MyClass(10)
    obj2 = MyClass(10)
    print(obj1 == obj2)  # 输出:True
    

__hash__(self)

  • 作用:定义对象的哈希值,支持将对象用作字典的键或添加到集合中。
  • 注意:如果重写了 __eq__,通常也需要重写 __hash__,以确保一致性。
  • 示例
    class MyClass:
        def __init__(self, value):
            self.value = value
    
        def __eq__(self, other):
            return self.value == other.value
    
        def __hash__(self):
            return hash(self.value)
    
    obj1 = MyClass(10)
    obj2 = MyClass(10)
    print(hash(obj1) == hash(obj2))  # 输出:True
    


4. 内存管理

__del__(self)

  • 作用:对象被销毁时调用,用于清理资源。
  • 注意:不推荐直接依赖它来管理资源,建议使用 try...finally 或上下文管理器 (with)。
  • 示例
    class MyClass:
        def __del__(self):
            print("Object is being deleted")
    
    obj = MyClass()
    del obj  # 输出:Object is being deleted
    

__sizeof__(self)

  • 作用:返回对象占用的内存大小(以字节为单位)。
  • 示例
    class MyClass:
        pass
    
    obj = MyClass()
    print(obj.__sizeof__())  # 输出:默认对象的内存大小
    


5. 其他通用方法

__getattribute__(self, name)

  • 作用:在访问属性时被调用。
  • 示例
    class MyClass:
        def __getattribute__(self, name):
            print(f"Accessing {name}")
            return super().__getattribute__(name)
    
        def __init__(self, value):
            self.value = value
    
    obj = MyClass(10)
    print(obj.value)  # 输出:Accessing value
    

__setattr__(self, name, value)

  • 作用:在设置属性时被调用。
  • 示例
    class MyClass:
        def __setattr__(self, name, value):
            print(f"Setting {name} to {value}")
            super().__setattr__(name, value)
    
    obj = MyClass()
    obj.value = 10  # 输出:Setting value to 10
    

__delattr__(self, name)

  • 作用:在删除属性时被调用。
  • 示例
    class MyClass:
        def __delattr__(self, name):
            print(f"Deleting {name}")
            super().__delattr__(name)
    
    obj = MyClass()
    obj.value = 10
    del obj.value  # 输出:Deleting value
    


6. 动态方法

__dir__(self)

  • 作用:自定义 dir() 函数的返回值。
  • 示例
    class MyClass:
        def __dir__(self):
            return ['custom_attribute']
    
    obj = MyClass()
    print(dir(obj))  # 输出:['custom_attribute']
    


总结:python的Object类是所有类的父类,其方法和属性有很多,在此不一一列举了,感兴趣可以查看object的源码注释

系统函数及其对应的类方法(表格)

以下是Python中常见系统函数及其对应的类方法的对比表格:

系统函数 对应类方法 描述
len(obj) obj.__len__() 返回对象的长度。
str(obj) obj.__str__() 返回对象的可读字符串表示。
repr(obj) obj.__repr__() 返回对象的“官方”字符串表示,用于调试或记录。
abs(obj) obj.__abs__() 返回对象的绝对值。
round(obj, ndigits) obj.__round__(ndigits) 返回对象四舍五入的值。
hash(obj) obj.__hash__() 返回对象的哈希值。
bool(obj) obj.__bool__() 返回对象的布尔值。
int(obj) obj.__int__() 将对象转换为整数。
float(obj) obj.__float__() 将对象转换为浮点数。
complex(obj) obj.__complex__() 将对象转换为复数。
bytes(obj) obj.__bytes__() 将对象转换为字节序列。
format(obj, spec) obj.__format__(spec) 返回对象的格式化字符串。
dir(obj) obj.__dir__() 返回对象的属性列表。
getattr(obj, name) obj.__getattribute__(name) 获取对象的属性值。
setattr(obj, name, value) obj.__setattr__(name, value) 设置对象的属性值。
delattr(obj, name) obj.__delattr__(name) 删除对象的属性。
callable(obj) obj.__call__() 检查对象是否可调用,若可调用则调用。
iter(obj) obj.__iter__() 返回对象的迭代器。
next(obj) obj.__next__() 返回迭代器的下一个值。
reversed(obj) obj.__reversed__() 返回对象的反向迭代器。
contains(obj, item) obj.__contains__(item) 检查对象是否包含某个项 (in 运算符)。
eq(a, b) a.__eq__(b) 检查两个对象是否相等 (==) 。
ne(a, b) a.__ne__(b) 检查两个对象是否不等 (!=) 。
lt(a, b) a.__lt__(b) 检查 a 是否小于 b (<) 。
le(a, b) a.__le__(b) 检查 a 是否小于等于 b (<=) 。
gt(a, b) a.__gt__(b) 检查 a 是否大于 b (>) 。
ge(a, b) a.__ge__(b) 检查 a 是否大于等于 b (>=) 。
add(a, b) a.__add__(b) 返回两个对象的加法结果 (+) 。
sub(a, b) a.__sub__(b) 返回两个对象的减法结果 (-) 。
mul(a, b) a.__mul__(b) 返回两个对象的乘法结果 (*) 。
truediv(a, b) a.__truediv__(b) 返回两个对象的浮点除法结果 (/) 。
floordiv(a, b) a.__floordiv__(b) 返回两个对象的整除结果 (//) 。
mod(a, b) a.__mod__(b) 返回两个对象的取模结果 (%) 。
pow(a, b) a.__pow__(b) 返回 ab 次幂 (**) 。
and_(a, b) a.__and__(b) 返回两个对象的按位与结果 (&) 。
or_(a, b) a.__or__(b) 返回两个对象的按位或结果 (`
xor(a, b) a.__xor__(b) 返回两个对象的按位异或结果 (^) 。
lshift(a, b) a.__lshift__(b) 返回对象的左移位结果 (<<) 。
rshift(a, b) a.__rshift__(b) 返回对象的右移位结果 (>>) 。
neg(obj) obj.__neg__() 返回对象的负数 (-obj) 。
pos(obj) obj.__pos__() 返回对象的正数 (+obj) 。
invert(obj) obj.__invert__() 返回对象的按位取反结果 (~obj) 。

这个表格列出了Python的系统函数与类方法之间的映射关系,方便查阅和理解两者的对应规则。

你可能感兴趣的:(python,开发语言)