1.new
创建对象实例,在实例对象被创建前调用,与之相对的是__init__,
__new__方法必须返回一个类的实例对象,通常情况下会调用父类的__new__方法来创建实例,并返回实例对象.
第一个参数是cls
__new__方法允许你控制实例的创建过程,可以实现自定义的逻辑.
单例模式,无论实例化多少次,始终都是同一个对象.
(回收站,文件夹等操作 )
class Single:
__instance =None
def __new__(cls, *args, **kwargs):
if not cls.__instance:
cls.__instance = super().__new__(cls)
return cls.__instance
def __init__(self):
pass
a = Single()
print(id(a))
a2 =Single()
print(id(a2))
del,
当对象被释放时,执行,通常用来执行一些资源释放或清理操作,如关闭文件.释放网络连接等.并不保证一定会调用.
__del__跟python中的关键字del没有关系
class Test:
def __init__(self):
print('__init__')
def __del__(self):
print('__init')
test = Test()
print(test)
垃圾回收机制,0的时侯回收
2.repr__和__len
__repr__用于定义对象的字符串表示形式,
__str__和__repr__两者用途不同,一个是给程序看的,一个是给人看的.
print(),str()调用str,交互模式下a,b会调用repr
__len__用于定于对象的长度大小,在对象上调用内置的len()函数时,python会查找对象是否定义了__len__方法,如果有则调用该方法并返回长度值
class List:
def __init__(self, items):
self.items = items
def __len__(self):
return len(self.items)
mylist = List([1,2,3,4])
print(len(mylist))
3.上下文协议
允许创建和可用于with语句的上下文管理器:使用上下文管理器可以在进入和推出代码块时执行特定操作,如资源分配和释放.
简化了异常捕获的代码,让异常捕获的封装性更好.
两者必须同时存在.
enter(self),
进入代码块前被调用,用于执行一些准备操作.
可以返回一个值,该值被赋给as关键字后面的变量
exit(self, exc_type, exc_value, exc_traceback)
在退出代码块时调用,无论代码块是否发生异常.
可以用于执行一些清理操作,如资源的释放.
若果代码块没有异常发生,参数都为None,如果有异常,参数包含异常类型,异常实例和跟踪信息
如果__exit__方法返回True,异常不会向上继续传播,返回False则异常会继续向上抛.
import logging
logger = logging.getLogger(__name__)
class FileHandler:
def __init__(self, filename, mode, encoding='utf-8'):
self.filename = filename
self.mode = mode
self.encoding = encoding
self.file = None
def __enter__(self):
self.file = open(self.filename, self.mode, encoding=self.encoding)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type:
logger.error(f'出错了,错误为{exc_val}')
if self.file:
print('文件正在关闭')
self.file.close()
return True
filehandler = FileHandler('ta.py', 'r',encoding='utf-8')
with filehandler as f:
con = f.read()
print(con)
4.可迭代对象和迭代器:
a_list = [1, 2, 3, 4]
aa_list = iter(a_list)
print(next(aa_list))
print(next(aa_list))
可迭代对象和迭代器是用来遍历数据集合的概念,在很多情况系下,用来实现数据的迭代操作.
可迭代对象:iterable
实现了__iter__()方法的都可以视为可迭代对象,列表,字典,元组,集合,字符串,
可以使用for循环遍历元素
可以使用iter()转换成迭代器
迭代器:iterator
实现了__iter__()和__next__()的方法的对象
iter()返回迭代器本身
next()返回迭代器的下一个元素
如果没有元素会抛出stopiteration异常
可以使用for循环遍历,也可以使用next()函数获取逐个元素
总结:
可迭代对象是具有迭代性质的对象,迭代器是一个实现了迭代协议的对象.
可迭代对象可以通过iter()方法转换成迭代器
迭代器是一种一次性的数据获取方式,每次调用next()获取下一个元素
from collections.abc import Iterator, Iterable
class MyFib:
def __init__(self, number):
self.number = number
def __iter__(self):
return FibIterator(self.number)
class FibIterator(Iterator):JICHENB
def __init__(self, max):
self.a = 0
self.b = 1
self.max = max
self.current = 0
def __next__(self):
self.current += 1
if self.current == 1:
return self.current
if self.current <= self.max:
self.a, self.b = self.b, self.a + self.b
return self.b
else:
raise StopIteration
my_fib = MyFib(5)
for fib in my_fib:
print(fib)
5.自定义序列
[ ]数据操作
getttem、steitem,delitem,用于自定义对象的索引访问和操作,他们在创建自定义容器类时非常有用,
5.1,getitem,
这个方法,方法定义了,使用索引访问对象时的行为,使用obj[key]进行索引操作时,会调用该方法,并将索引key作为参数传递给这个方法,
迭代,没有iter方法时会退而求其次选择__getitem__方法
class MyNumbers:
def __init__(self, numbers):
self.numbers = numbers
def __getitem__(self, item):
num = self.numbers[item]
return num
a_list = [1, 2, 3, 4, 5, 6]# a_dict也可以 my_number['key']
my_numbers = MyNumbers(a_list)
print(my_numbers[2])
s = slice()
list[s]
列表切片返回的是列表,元组切片返回的是元组
按理说应该返回与原本数据类型一样的数据类型
if isinstance(item, slice):
temp = self.numbers[item]
cls = type(self)
obj = cls(temp)
return obj
else:
num = self.numbers[item]
return num
def __str__(self):
return f"{self.numbers}"
contains,
def __contains__(self, item):
return item in self.numbers
5.2,setitem
这个方法定义了使用索引赋值操作时的行为,使用obj[key] = value 时,会调用该方法,并将key和value的值作为参数进行传递.\
def __setitem__(self, key, value):
self.numbers[key] = value
5.3 delitem
定义使用del obj[key]进行索引删除操作时的行为.
def __delitem__(self, key):
self.numbers.pop(key)
6.属性相关
getattr,setattr,delattr
用于自定义对象的属性访问和操作,允许控制属性的获取,设置和删除行为,从而实现自定义的属性操作逻辑
getattr(self, name)
当访问不存在属性,会调用该方法,将name作为参数传递给该方法,可以在这个方法里面实现返回默认值或者抛出异常
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def __getattr__(self, item):
return 1
person = Person('wangwu', 18)
print(person.name)
print(person.gender)
return self.dic[key]
setattr,对属性的设置进行限制,设置属性就会触发.将属性名name和值value作为参数传递给该方法,可以在这个方法中实现对应的赋值操作,进行值的修改或验证.
需要调用父类方法
def __setattr__(self, key, value):
print(f'接收参数key的值{key},接收参数value的值{value}')
super().__setattr__(key, value)
无限递归的问题
delatr(self, name)删除属性时,会调用该方法,并将name作为参数传递给该方法.,可以实现删除属性的逻辑
def __delattr__(self, item):
if item in ['xxx', 'xxxxx']:
raise AttributeError(f'{item!r}为基础属性,不可删除')
super(Person, self).__delattr__(item)
7.可调用的
类里面实现__call__方法就可以进行调用
def call(self, 参数)
与装饰器一起使用
8.运算符
def lt(self, other):
return self.___< other.value
__gt__同理 >
eq = !=同样可以使用
ne 不等于
__le__小于等于
__ge