目录
[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 创建对象实现单例模式)
一、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 面向对象编程的完整体系,使开发者能够构建灵活、可维护的应用程序。