进阶版:Python面向对象

目录

一、attr相关内置函数

[1.hasattr(obj, 'attr')](#1.hasattr(obj, 'attr'))

[2.setattr(obj, name, value)](#2.setattr(obj, name, value))

[3.getattr(obj, name[, default])](#3.getattr(obj, name[, default]))

[4.delattr(obj, name)](#4.delattr(obj, name))

[5.next(iterator[, default])](#5.next(iterator[, default]))

[6.iter(obj[, sentinel])](#6.iter(obj[, sentinel]))

二、属性封装

三、单例类

[1.new 创建对象实现单例模式](#1.new 创建对象实现单例模式)

2.装饰器实现单例模式

3.元类与__call__结合的单例类

四、元类

五、抽象基类

六、可迭代对象

七、迭代器

八、生成器

方法一:元组推导式

方法二:yield关键字

总结



一、attr相关内置函数

1.hasattr(obj, 'attr')

检查对象是否具有指定属性,返回布尔值(True/False)。

python 复制代码
class Person:
    name = "Alice"

p = Person()
print(hasattr(p, 'name'))  # True
print(hasattr(p, 'age'))   # False

2.setattr(obj, name, value)

设置对象的属性值(若属性不存在则创建)。

  • obj:目标对象

  • name:属性名(字符串)

  • value:要设置的值

python 复制代码
class Person:
    pass

p = Person()
setattr(p, 'name', 'Bob')
print(p.name)  # 'Bob'

3.getattr(obj, name[, default])

获取对象属性值。

default:可选,属性不存在时返回的默认值

python 复制代码
class Person:
    age = 25

p = Person()
print(getattr(p, 'age'))        # 25
print(getattr(p, 'height', 180))  # 180(默认值)

4.delattr(obj, name)

删除对象属性。

python 复制代码
class Person:
    name = "Charlie"

p = Person()
delattr(p, 'name')
print(hasattr(p, 'name'))  # False

5.next(iterator[, default])

从迭代器中获取下一个元素。

  • iterator:迭代器对象

  • default:可选,迭代结束时返回的默认值

python 复制代码
nums = iter([1, 2, 3])
print(next(nums))  # 1
print(next(nums))  # 2
print(next(nums, 'End'))  # 3
print(next(nums, 'End'))  # 'End'

6.iter(obj[, sentinel])

获取对象的迭代器。

  • obj:可迭代对象

  • sentinel:可选,哨兵值(当调用返回此值时停止迭代)

python 复制代码
# 基本用法
lst = [1, 2, 3]
i = iter(lst)
print(next(i))  # 1

# 带哨兵值的用法(常用于读取文件/流直到特定标记)
class Counter:
    def __init__(self):
        self.count = 0
    
    def __call__(self):
        self.count += 1
        return self.count

c = Counter()
i = iter(c, 3)  # 当c()返回3时停止
print(list(i))  # [1, 2]

二、属性封装

在Python中,属性封装通常指的是将对象的属性隐藏起来,并提供公共方法来访问和修改这些属性。这样做的好处包括提高代码的安全性、封装性以及易于维护。@property装饰器提供了一种方法来封装属性的访问和修改,使得属性的访问和修改可以通过方法调用来实现,而不是直接访问属性。这不仅可以控制对属性的访问,还可以添加额外的逻辑,如验证或转换。

python 复制代码
# 允许你将方法转换为属性,从而实现对属性的封装和控制。
class Person:
    def __init__(self, name):
        self.__name =name

    @property
    def get_name(self):
        return self.__name

    @get_name.setter
    def get_name(self, name):
        self.__name = name

p = Person("张飞")
print(p.get_name)

三、单例类

1.__new__ 创建对象实现单例模式

python 复制代码
class PersonManage:
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, "instance"):
            instance = super().__new__(cls)
            setattr(cls, "instance", instance)
        return getattr(cls, "instance")

p1 = PersonManage()
p2 = PersonManage()
print(p1 is p2)

2.装饰器实现单例模式

python 复制代码
def singleton(cls):
    instance = {}
    def wrap(*args):
        if cls not in instance:
            instance[cls] = cls(*args)
        return instance[cls]
    return wrap

@singleton
class PersonManage:
    pass


p1 = PersonManage()
p2 = PersonManage()
print(p1 is p2)

3.元类与__call__结合的单例类

python 复制代码
class SingleTon(type):
    instance = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls.instance:
            cls.instance[cls] = super.__call__(*args, **kwargs)
        return cls.instance[cls]

class PersonManage(metaclass=SingleTon):
    pass

p1 = PersonManage()
p2 = PersonManage()
print(p1 is p2)

四、元类

元类:用于控制类的创建行为。简单来说,元类是类的类; Python 中所有的类都是由 type 创建的,type 是所有类的默认元类

python 复制代码
class MyType(type):
    def __new__(cls, name, bases, dic):
        print(name, bases, dic)
        instance = super().__new__(cls, name, bases, dic)
        temp = {}
        for k, v in dic.items():
            if not k.startswith("__"):
                temp[k.lower()] = v
            else:
                temp[k] = v
        print(temp)
        print(id(instance))
        return instance


class Person(metaclass=MyType):
    INFO = "HELLO"
    def __init__(self, name):
        self.name = name

print(Person, id(Person))
p = Person("李明")
print(p.name)

五、抽象基类

三点注意:1.****子类必须实现所有抽象方法才能实例化。

2.不能直接实例化抽象基类,会报错。

3.继承ABC基类,使类成为抽象基类。

案例一:三层的继承关系,Person的子类必须要实现move()方法,否则会报错。Person的孙类Book可以不用实现重写move()方法,即表明在三代关系中,只需要子类实现重写父类方法就行。

python 复制代码
from abc import  ABC, abstractmethod

class Person(ABC):
    # 抽象类不能直接实例化, 子类必须实现所有的抽象方法
    @abstractmethod
    def move(self):
        pass

class Student(Person):
    def move(self):
        print("我每天跑步的平均速度在10km/h附近")

class Book(Student):
    # pass
    def move(self):
        print("每天都会阅览一本书")


student = Student()
student.move()

book = Book()
book.move()

案例二:形状绘制器,计算图形的面积。

python 复制代码
from abc import ABC, abstractmethod
import math

# 继承ABC基类,使类成为抽象基类;
# 不能直接实例化抽象基类;
# 子类必须实现所有抽象方法才能实例化


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

class Square(Shape):
    # 定义一个正方形的边长
    def __init__(self, side):
        self.side = side

    # 计算面积
    def area(self):
        return self.side ** 2


class Triangle(Shape):
    # 定义三角形的三条边分别为a, b, c
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    # 如果没有抽象方法"area"的实现,则无法实例化抽象类Triangle
    def area(self):
        # 通过海伦公式计算三角形的面积
        s = (self.a + self.b + self.c) / 2
        return math.sqrt(s * (s - self.a) * (s - self.b) * (s - self.c))

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

    def area(self):
        return self.radius ** 2 * math.pi


sq = Square(5)
tr = Triangle(3, 4, 5)
ci = Circle(5)
print(f"正方形的面积是{sq.area()}")
print(f"三角形的面积是{tr.area()}")
print(f"圆的面积是{ci.area()}")

六、可迭代对象

可迭代对象:实现了__iter__方法,可以使用for遍历。

所有的容器数据类型都是可迭代的(iterable)例如列表,字典,元组,集合。

python 复制代码
from collections.abc import Iterable
data1 = [1, 2, 3, 4, 5]
data2 = (1, 2, 3 , 4, 5)
data3 = {"id": 101, "age": 21, "name": "李明"}
data4 = {1, 2, 3, 4, 5}
print(isinstance(data1, Iterable)) # True
print(isinstance(data2, Iterable)) # True
print(isinstance(data3, Iterable)) # True
print(isinstance(data4, Iterable)) # True

七、迭代器

迭代器(iterator):实现了__iter__、__next__方法, 可以使用for遍历,next方法取值。

python 复制代码
class MyIterator:
    def __init__(self, datas, index):
        self.datas = datas
        self.index = index

    def __iter__(self):
        return iter(self.datas)

    def __next__(self):
        """实现__next__的前提是实现__iter__
        任何一个迭代器都是可迭代类型"""
        if 0 <= self.index < len(self.datas):
            value = self.datas[self.index]
            self.index += 1
            return value
        else:
            # return False
            raise StopIteration("超出范围了")
mt = MyIterator([100, 200, 300, 400, 500], 0)
for e in mt:
    print(e)
print(next(mt))
print(next(mt))
print(next(mt))
print(next(mt))
print(next(mt))
print(next(mt))

八、生成器

生成器优点:特殊的迭代器,可以节省内存。

缺点:不能直接的获取指定位置的元素(需要按照顺序从前向后依次获取,直到目标值。)

方法一:元组推导式

python 复制代码
from collections.abc import Iterable, Iterator, Generator
import sys
# 元组推导式
datas = [i for i in range(100)]

items = (i for i in range(100))

print(isinstance(items, Iterator), isinstance(items, Iterable), isinstance(items, Generator))
# 生成器:节省内存

print(sys.getsizeof(datas))
print(sys.getsizeof(items))

for e in range(100):
    print(next(items))

方法二:yield关键字

python 复制代码
def my_fun():
    for i in range(10):
        yield i

r = my_fun()
print(type(r), r)
for e in range(10):
    print(next(r))

总结

Python 提供了一系列 attr 相关内置函数(hasattr/setattr/getattr/delattr)来实现动态属性操作,这些函数与对象的 \\getattribute\\、\\setattr\\ 等魔术方法协同工作,构成了 Python 强大的反射机制。在面向对象编程中,属性封装通过公有/私有控制实现了数据隐藏,而单例模式则可通过 \\new\\ 方法、装饰器或元类结合 \\call\\ 等多种方式实现,确保类只有一个实例。元类(type 的子类)作为"类的类",可以深度控制类的创建过程,常用于框架开发。抽象基类(abc 模块)通过 @abstractmethod 强制子类实现特定接口,体现了面向对象的抽象特性。迭代相关概念包含可迭代对象(实现 \\iter\\)、迭代器(实现 \\next\\)和生成器(yield 或生成器表达式),它们共同构成了 Python 迭代器协议,支持惰性计算和高效的内存使用。这些特性从基础到高级,构成了 Python 面向对象编程的完整体系,使开发者能够构建灵活、可维护的应用程序。

相关推荐
王国强20091 分钟前
Pydantic 深度指南:Python 类型安全与数据建模的现代解决方案
python
天宁30 分钟前
TCP粘包问题解决方案
python
站大爷IP32 分钟前
Python循环嵌套:从入门到实战的完整指南
python
树獭叔叔1 小时前
Python 锁机制详解:从原理到实践
后端·python
2025年一定要上岸1 小时前
【Django】-10- 单元测试和集成测试(下)
数据库·后端·python·单元测试·django·集成测试
用户576905308011 小时前
Python实现一个类似MybatisPlus的简易SQL注解
后端·python
程序猿小郑1 小时前
文本转语音(TTS)脚本
python
reasonsummer2 小时前
【教学类-52-17】20250803动物数独_空格尽量分散_只有一半关卡数(N宫格通用版3-10宫格)0图、1图、2图、6图、有答案、无答案 组合版24套
python
上官鹿离2 小时前
Selenium教程(Python 网页自动化测试脚本)
python·selenium·测试工具