第三章 深入类和对象

目录

​编辑4.1 鸭子类型和多态

深入解释

4.2 抽象基类(abc模块)

深入解释

4.3 使用isinstance而不是type

深入解释

4.4 类变量和对象变量

深入解释

4.5 类属性和实例属性以及查找顺序

深入解释

4.6 静态方法、类方法以及对象方法

深入解释

4.7 数据封装和私有属性

深入解释

4.8 Python对象的自省机制

深入解释

4.9 super函数

深入解释

4.10 Django REST Framework中对多继承使用的经验

深入解释

4.11 Python中的with语句

深入解释

4.12 contextlib实现上下文管理器

深入解释

4.13 本章小结


4.1 鸭子类型和多态

鸭子类型(Duck Typing)是一种动态类型的理念,来源于"如果它走路像鸭子,叫声像鸭子,那么它就是鸭子"。在这种类型系统中,关注的是对象的行为,而不是其实际类型。多态(Polymorphism)是面向对象编程中的一个重要概念,指的是同一接口调用不同类型的对象时,表现出不同的行为。

深入解释

鸭子类型的关键在于,它使得代码更加灵活和易于扩展。多态允许我们编写更通用的代码,无需关心对象的具体类型,只要对象实现了所需的方法即可。

高级示例代码:

class Bird:
    def make_sound(self):
        print("Tweet, tweet!")

class Dog:
    def make_sound(self):
        print("Bark, bark!")

def animal_sound(animal):
    animal.make_sound()

animals = [Bird(), Dog()]
for animal in animals:
    animal_sound(animal)

在这个示例中,animal_sound函数对任何实现了make_sound方法的对象都有效,这展示了多态的威力。

4.2 抽象基类(abc模块)

抽象基类(Abstract Base Class, ABC)定义了一组方法,要求其子类必须实现这些方法。Python的abc模块用于创建抽象基类,确保子类实现必要的方法。

深入解释

抽象基类的主要作用是为类的设计提供一种规范,强制子类实现特定的接口。这在大型项目中尤其有用,确保了代码的一致性和可维护性。

高级示例代码:

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

    @abstractmethod
    def perimeter(self):
        pass

class Rectangle(Shape):
    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)

rectangle = Rectangle(5, 10)
print(f"Area: {rectangle.area()}")  # Area: 50
print(f"Perimeter: {rectangle.perimeter()}")  # Perimeter: 30

4.3 使用isinstance而不是type

isinstance函数用于检查对象是否是某个类的实例,推荐使用它而不是type,因为isinstance支持继承关系。

深入解释

使用isinstance可以更灵活地进行类型检查,尤其在处理继承结构时。它不仅检查对象是否属于指定类,还会检查是否属于该类的子类。

高级示例代码:

class Animal:
    pass

class Mammal(Animal):
    pass

class Dog(Mammal):
    pass

dog = Dog()

print(isinstance(dog, Animal))  # True
print(isinstance(dog, Mammal))  # True
print(isinstance(dog, Dog))     # True
print(type(dog) == Animal)      # False
print(type(dog) == Mammal)      # False
print(type(dog) == Dog)         # True

4.4 类变量和对象变量

类变量(class variable)和对象变量(instance variable)的区别在于类变量是所有实例共享的,而对象变量是每个实例独有的。

深入解释

类变量在所有实例间共享,修改类变量会影响所有实例。对象变量则在实例间独立存在,修改一个实例的对象变量不会影响其他实例。

高级示例代码:

class MyClass:
    class_variable = 'I am a class variable'

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

obj1 = MyClass('I am obj1 instance variable')
obj2 = MyClass('I am obj2 instance variable')

print(MyClass.class_variable)  # I am a class variable
print(obj1.instance_variable)  # I am obj1 instance variable
print(obj2.instance_variable)  # I am obj2 instance variable

# 修改类变量
MyClass.class_variable = 'Class variable changed'
print(obj1.class_variable)  # Class variable changed
print(obj2.class_variable)  # Class variable changed

4.5 类属性和实例属性以及查找顺序

在Python中,当访问一个属性时,解释器会先在实例的字典中查找,然后在类的字典中查找,再在父类的字典中查找。

深入解释

这种查找顺序确保了实例属性可以覆盖类属性,同时允许通过继承机制访问父类的属性。

高级示例代码:

class MyClass:
    variable = 'Class variable'

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

obj = MyClass('Instance variable')

print(obj.variable)  # Instance variable
print(MyClass.variable)  # Class variable

# 删除实例属性
del obj.variable
print(obj.variable)  # Class variable

4.6 静态方法、类方法以及对象方法

Python提供了三种方法类型:静态方法(staticmethod)、类方法(classmethod)和实例方法(instance method)。

深入解释

静态方法不需要实例化即可调用,通常用于工具函数;类方法操作类本身,通常用于工厂方法;实例方法操作实例,最常见。

高级示例代码:

class MyClass:
    @staticmethod
    def static_method():
        print("Static method called")

    @classmethod
    def class_method(cls):
        print("Class method called")

    def instance_method(self):
        print("Instance method called")

MyClass.static_method()  # Static method called
MyClass.class_method()   # Class method called
obj = MyClass()
obj.instance_method()    # Instance method called

4.7 数据封装和私有属性

数据封装通过限制对某些属性的访问来保护数据的完整性。Python通过双下划线实现私有属性(private attribute),避免外部直接访问。

深入解释

使用私有属性可以避免外部直接修改内部数据,增强代码的安全性和可维护性。通过getter和setter方法可以间接访问和修改私有属性。

高级示例代码:

class MyClass:
    def __init__(self):
        self.__private_variable = "I am a private variable"

    def get_private_variable(self):
        return self.__private_variable

    def set_private_variable(self, value):
        self.__private_variable = value

obj = MyClass()
print(obj.get_private_variable())  # I am a private variable

obj.set_private_variable("New value")
print(obj.get_private_variable())  # New value
# print(obj.__private_variable)  # AttributeError: 'MyClass' object has no attribute '__private_variable'

4.8 Python对象的自省机制

自省(Introspection)是Python的一种能力,可以在运行时获取对象的类型和属性。这在调试和动态特性中非常有用。

深入解释

自省机制允许我们在运行时检查对象的类型、属性和方法,帮助开发者动态地操作对象。

高级示例代码:

class MyClass:
    def __init__(self, value):
        self.value = value

    def method(self):
        pass

obj = MyClass(10)

print(dir(obj))         # 打印对象的所有属性和方法
print(obj.__class__)    # 打印对象所属的类
print(obj.__dict__)     # 打印对象的属性字典

4.9 super函数

super函数用于调用父类的方法,特别是在多重继承中,super函数可以避免显式地调用父类,提供一种动态的解决方案。

深入解释

super函数不仅用于初始化父类,还可用于调用父类的任何方法。它在多重继承中尤其有用,可以确保所有父类的初始化方法都被调用。

高级示例代码:

class Parent:
    def __init__(self):
        print("Parent init")

    def method(self):
        print("Parent method")

class Child(Parent):
    def __init__(self):
        super().__init__()
        print("Child init")

    def method(self):
        super().method()
        print("Child method")

child = Child()
child.method()

4.10 Django REST Framework中对多继承使用的经验

在Django REST framework中,多继承常用于组合视图行为,避免重复代码。例如,使用混入(Mixin)类来组合不同的功能。

深入解释

Django REST framework中的混入类提供了一种灵活的方法来重用视图逻辑。通过多重继承,我们可以轻松地组合不同的功能,而无需重复编写相同的代码。

高级示例代码:

from rest_framework import generics, mixins
from .models import MyModel
from .serializers import MySerializer

class MyView(mixins.ListModelMixin,
             mixins.CreateModelMixin,
             generics.GenericAPIView):
    queryset = MyModel.objects.all()
    serializer_class = MySerializer

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

4.11 Python中的with语句

with语句用于简化资源管理,确保资源在使用完毕后正确关闭或释放。常见的使用场景包括文件操作和数据库连接。

深入解释

with语句使用上下文管理器(context manager)来管理资源。上下文管理器定义了__enter____exit__方法,在资源进入和退出上下文时调用。

高级示例代码:

with open('file.txt', 'r') as file:
    content = file.read()
    print(content)

在这个示例中,无论是否发生异常,文件都会正确关闭。

4.12 contextlib实现上下文管理器

contextlib模块提供了用于实现上下文管理器的工具,使得编写简洁的上下文管理器变得更加容易。

深入解释

使用contextlib.contextmanager装饰器可以将生成器函数转换为上下文管理器,从而简化了上下文管理器的实现。

高级示例代码:

from contextlib import contextmanager

@contextmanager
def simple_context_manager():
    print("Enter")
    yield
    print("Exit")

with simple_context_manager():
    print("Inside the context")

在这个示例中,simple_context_manager生成器函数实现了上下文管理器,确保进入和退出上下文时执行特定代码。

4.13 本章小结

在本章中,我们深入探讨了Python的类和对象,包括鸭子类型、抽象基类、属性查找顺序、数据封装、对象自省等概念。通过实例代码,我们展示了如何在实际编程中应用这些概念,提升代码的组织性和可维护性。

希望这篇博客能帮助您更好地理解Python中的类和对象的相关知识。如果您有任何进一步的问题或需要更详细的解释,请随时告诉我!

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

湘大小菜鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值