class Course(object):
def __init__(self, name, price):
self.name = name
self.price = price
def __str__(self):
return "func is __str__ ,课程:{},价格:{}".format(self.name, self.price)
#
python = Course("python", 25000)
print(python) # func is __str__ ,课程:python,价格:25000
print("%s" % (python)) # func is __str__ ,课程:python,价格:25000
print([python]) # [<__main__.Course object at 0x000001CAEB38F438>]
class Course(object):
def __init__(self, name, price):
self.name = name
self.price = price
def __repr__(self):
return "func is __repr__ ,课程:{},价格:{}".format(self.name, self.price)
python = Course("python", 25000)
print(python) # func is __repr__ ,课程:python,价格:25000
print("%r" % (python)) # func is __repr__ ,课程:python,价格:25000
print([python]) # [func is __repr__ ,课程:python,价格:25000]
python = Course("python", 25000)
class Course(object):
def __init__(self, name, price):
self.name = name
self.price = price
def __str__(self):
return "func is __str__ ,课程:{},价格:{}".format(self.name, self.price)
def __repr__(self):
return "func is __repr__,课程:{},价格:{}".format(self.name, self.price)
python = Course("python", 25000)
print(python) # func is __str__ ,课程:python,价格:25000
print("%s" % (python)) # func is __str__ ,课程:python,价格:25000
print([python]) # [func is __repr__,课程:python,价格:25000]
print(repr(python)) # func is __repr__,课程:python,价格:25000
print("%r" % (python)) # func is __repr__,课程:python,价格:25000
总结:
# 如果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 Course(object):
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
class Python(Course):
pass
# def __repr__(self): # 备胎
# return '%s--%s--%s'%(self.name,self.price,self.period)
# def __str__(self):
# return '全栈开发 :'+self.name
py20 = Python('python',25000,'6 months')
print(py20)
打印对象 先走自己的str,如果没有,走父类的,如果除了object之外的所有父类都没有str
再回来,找自己的repr,如果自己没有,再找父类的
repr是str的备胎
和所有的字符串格式化以及直接打印这个对象相关
有了repr或者str在打印对象的时候 就不会显示用户不关心的内存地址了
增强了用户的体验 在程序开发的过程中
如果我们需要频繁打印对象中的属性,需要从类的外部做复杂的拼接,实际上是一种麻烦
如果这个拼接工作在类的内部已经完成了,打印对象的时候直接就能显示
__new__ 构造方法 生产对象的时候用的 - 单例模式.
__del__ 析构方法 在删除一个对象之前用的 - 归还操作系统资源.
class Foo(object):
def __new__(cls, *args, **kwargs): # 这里不能将cls换成self.原因在这里,self还没有被创建出来
print("创建对象呀!") # 先执行
obj = object.__new__(cls) # self被创建出来
print(obj) # <__main__.Foo object at 0x00000158F978C9E8>
return obj
def __init__(self):
print("初始化!!") # 后执行
print(self) # <__main__.Foo object at 0x00000158F978C9E8>
f = Foo()
'''
创建对象呀!
<__main__.Foo object at 0x00000158F978C9E8>
初始化!!
<__main__.Foo object at 0x00000158F978C9E8>
'''
实例化一个Foo对象,先开辟一块空间,使用的是Foo这个内部的__new__,如果内部没有这个__new__方法,则会调用object类中的__new__方法
在使用self之前,都还有一个生产self的过程,就是在内存空间开辟属于这个对象的空间,并且在这个内存空间存放一个类指针,也上就是__new__所做的事情。
一个类 有且只能有一个实例
class Foo(object):
__flag = None
def __new__(cls, *args, **kwargs):
if cls.__flag is None:
obj = object.__new__(cls)
cls.__flag = obj
return cls.__flag
保证一个类无论 被实例化多少次,只开辟一次空间,始终使用的是同一块内存地址
class Foo(object):
def __init__(self, name,age):
self.name = name
self.age = age
def __del__(self):
print("执行我了")
print("ddabhjdab")
f = Foo("Tom", 45)
print(f.__dict__) # {'name': 'Tom', 'age': 45}
del f.name # 只和del obj语法有关系,在执行del obj之前会来执行一下__del__中的内容
print(f.__dict__)
'''
{'age': 45}
执行我了
'''
class File(object):
def __init__(self, path):
self.f = open(path, 'w',encoding='utf-8')
def __del__(self):
self.f.close()
f = File("XXXX")
在所有的代码都执行完毕之后,所有的值都会被python解释器回收
python解释器清理内存
## __call__
对象()自动触发__call__中的内容
class Foo(object):
def __init__(self, name):
self.name = name
def __call__(self, *args, **kwargs):
print("name " + self.name)
# f = Foo("Tom")
# f() # name Tom
Foo("Mack")() # name Mack # 对象+()就会调用__call__()方法
class Foo(object):
def __enter__(self):
print("开始")
def __exit__(self, exc_type, exc_val, exc_tb):
print("结束!")
with Foo():
print('aaaa')
'''
开始
aaaa
结束!
'''
class Myopen(object):
def __init__(self,path,mode):
self.path = path
self.mode = mode
def __enter__(self):
self.f = open(self.path,self.mode)
return self.f
def __exit__(self, exc_type, exc_val, exc_tb):
self.f.close()
with open("test", 'a') as file: # file == self.f
file.write('hello world')
import pickle
class PickleDump(object):
def __init__(self, path, mode):
self.path = path
self.mode = mode
def __enter__(self):
self.f = open(self.path, self.mode)
return self
def dump(self, obj):
pickle.dump(obj, self.f)
def __exit__(self, exc_type, exc_val, exc_tb):
self.f.close()
with PickleDump("pickle_file", 'ab') as file:
file.dump("abcde")
file.dump("abcde")
file.dump("abcde")
file.dump("abcdea")
import pickle
class PickleLoad(object):
def __init__(self, path, mode):
self.mode = mode
self.path = path
def __enter__(self):
self.f = open(self.path, self.mode)
return self
def load(self):
while True:
try:
f = pickle.load(self.f)
yield f
except EOFError as f:
break
def __exit__(self, exc_type, exc_val, exc_tb):
self.f.close()
with PickleLoad('pickle_file', 'rb') as file:
for read_line in file.load():
print(read_line)
class Foo(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __enter__(self):
print("开始了")
def __exit__(self, exc_type, exc_val, exc_tb):
print("结束了")
with Foo("Tom", 45):
print("func")
'''
开始了
func
结束了
'''
原文:https://www.cnblogs.com/yangchangjie150330/p/10642845.html