一.
__str__/__repr__
where:在打印对象 ( print(obj) / print(repr(obj) )或用%s,%r格式化输出时候自动执行
how:有了repr或者str在打印对象的时候 就不会显示用户不关心的内存地址了
增强了用户的体验 在程序开发的过程中
如果我们需要频繁打印对象中的属性,需要从类的外部做复杂的拼接,实际上是一种麻烦
如果这个拼接工作在类的内部已经完成了,打印对象的时候直接就能显示
结果: 如果 不实现str/repr方法,那么对象打印出来只是一串地址
如果str存在,repr也存在
那么print(obj)和使用字符串格式化format,%s这两种方式 调用的都是__str__
而repr(obj)和%r格式化字符串,都会调用__repr__
如果str不存在,repr存在
那么print(obj),字符串格式化format,%s,%r 和repr(obj)都调用__repr__
如果str存在,repr不存在
那么print(obj)和使用字符串格式化format,%s这两种方式 调用的都是__str__
___repr(obj)和%r格式化字符串 都会打印出内存地址
class Courese:
def __init__(self,name,price,period):
self.name=name
self.price=price
self.period=period
def __repr__(self):
return '%s,%s,%s' % (self.name, self.price, self.period)
def __str__(self):
return self.name
python=Courese('python',25000,'6months')
print(python) #没有输出格式,>>>><__main__.Courese object at 0x000002B48D97DE80>
print(python) #有__str >>>python
print(python) #有 __repr >>>python,25000,6months
print(python) #都有时,执行__str不执行__repr,>>>python
print(repr(python)) #>>>都有 ython,25000,6months
print('course %r'%python) #都有 course python,25000,6months
又是我们在继承中会遇到有str_与repr_情况,子类父类的不同方法,需要我们选择:
对于当前类,如果自己没有str,就找父类的str.如果父类都没有,那开始找repr,在没有继续向上找
二.
类实例化对象的初始化方法,传参给self生成对象obj
__new__构造方法 生产对象的时候用-----
构造方法__new__
的执行是由创建对象触发的,即:对象 = 类名()
1 class Base(object): 2 def __new__(cls, *args, **kwargs): 3 ''' 4 构造方法:开辟空间,创键空对象self 5 :param args: 6 :param kwargs: 7 :return: 8 ''' 9 return object.__new__(cls) #self 10 def __init__(self): 11 ''' 12 初始化方法,给空self传参,创造实例化对象 13 ''' 14 self.x=1 15 obj=Base() #先执行new方法,在init方法实例 16 print(obj) 17 print(obj.x)
单例模式_设计模式_一个类只能有一个实例化对象
一个类无论实例化多少次,只开辟一次空间,始终用同一块内存地址
1 class A:
2 __flag=None #增加限制
3 def __new__(cls, *args, **kwargs): #生产self的动作
4 if cls.__flag is None: #回应,条件设置限制
5 cls.__flag=object.__new__(cls) #这里才开辟空间创造self
6 return cls.__flag #返回实际为self空间,存储类指针
7 def __init__(self,name=None,age=None):
8 self.name=name
9 if age:
10 self.age=age
11 a1=A('alex',84)
12 print(a1)
13 a2=A('alex',83) #a1与a2相同的地址
14 print(a2)
15 print(a1.age) #此处a2已经覆盖a1>>>83
三.
__del__析构方法 在删除一个对象之前用的 _归还操作系统资源
python解释器清理内存
1.我们主动删除 del obj
2.python解释器周期性删除
3.在程序结束之前 所有的内容都需要清空
import time
class A:
def __init__(self,path):
self.f=open(path,'w')
def __del__(self): #只与del obj 相关,执行删除对象前先执行者动作
#归还操作系统资源,包括文件\网络\数据库连接,在程序执行完后,自动执行
self.f.close()
a=A('userinfo')
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
四.
__call__源码中用的比较多,对象() 会自动触发__call__中的内容
class A:
def call(self):
print('in call')
def __call__(self, *args, **kwargs):
print('in __call__')
A()() #in __call__
obj = A()
obj() #in __call__ 对象加括号,直接调用__call__的动作
obj.call() #in call
五.with 上下文处理 文件操作类
with 语句,就是__enter__,执行前动作,__exit__执行后动作
在一个函数的前后添加功能,类似装饰器函数中的内容
1 import pickle #调用pickle模块文件操作
2 class Mypicledump: #创建文件写入的类
3 def __init__(self,path,mode='ab'): #文件操作必要属性传入
4 self.path=path
5 self.mode=mode
6 def __enter__(self): #函数动作前的打开文件操作
7 self.f=open(self.path,self.mode)
8 return self #返回要操作的文件
9 def dump(self,obj):
10 pickle.dump(obj,self.f) #写入文件的动作
11 def __exit__(self, exc_type, exc_val, exc_tb):
12 self.f.close() #写入结束后关闭文件
13 with Mypicledump('pickle_file') as obj: #实例化一个文件做对象,对象句柄为obj
14 obj.dump({1,2,3,4}) #对象(句柄)加点.加动作函数(包含写入参数)
15
16
17 class MypickelLoad: #定义文件查看类
18 def __init__(self,path,mode='rb'): #必要属性传入
19 self.path=path
20 self.mode=mode
21 def __enter__(self): #动作前打开文件
22 self.f=open(self.path,self.mode)
23 return self #self为打开待执行的文件
24 def loaditer(self): #读取文件用生成器节省内存
25 while True:
26 try: #迭代器超出范围错误处理
27 ret = pickle.load(self.f) #实际读取动作
28 yield ret #生成器
29 except EOFError:
30 break
31 def __exit__(self, exc_type, exc_val, exc_tb):
32 self.f.close() #结束文件操作
33 with MypickelLoad('pickle_file')as mypic: #创建读取文件类的对象,文件句柄mypic
34 for obj in mypic.loaditer(): #用for循环查看对象动作后生成器内容
35 print(obj) #查看内容
文件操作的写入,读取模板,创建类的对象执行即可使用
六.
把对象的属性与值格式化为字典输入查看所有属性(包括隐藏属性)
print(obj.__dict__
)
1 class School: 2 def __init__(self,name,addr,type): 3 self.name=name 4 self.addr=addr 5 self.__tpye=type 6 obj=School('老男孩','北京','教育') 7 print(obj.__dict__) 8 {'name': '老男孩', 'addr': '北京', '_School__tpye': '教育'}
七,item
1 class Foo: 2 def __init__(self,name): 3 self.name=name 4 5 def __getitem__(self, item): 6 print(self.__dict__[item]) 7 8 def __setitem__(self, key, value): 9 self.__dict__[key]=value 10 11 def __delitem__(self, key): 12 print('del obj[key]时,执行我方法') 13 self.__dict__.pop(key) 14 15 def __delattr__(self, item): 16 print('del obj.key时,执行我方法') 17 self.__dict__.pop(item) 18 19 f1=Foo('666') 20 print(f1.name) #查看属性 21 f1['age']=18 #添加属性用setitem 方法 22 print(f1.age) 23 print(f1[age]) #查看属性调用getitem 方法 24 f1['name']='alex' #改变属性,setitem 方法 25 print(f1.__dict__) 26 del f1['age'] #删除属性,调用delitem 方法 27 print(f1.__dict__) 28 #del f1.age #删除属性,调用delattr 方法 29 #print(f1.__dict__)
八.