面向对象进阶
面向对象进阶
__new__
,__init__
__new__
负责对象的创建,__init__
负责对象的初始化
Python2.x
中类的定义分为新式定义和老式定义两种。老式类定义时不继承 object 基类,而新式类在定义时显示继承 object 类。
# Python2.x中的老式类定义
class A:
pass
# Python2.x中的新式类定义
class A(object):
pass
注意:实例化对象是object类底层实现,其他类继承了object的__new__
才能够实例化对象。
Python3.x
中没有新式类和老式类,它们都继承自 object 类。因此可以不用显示地指定其基类。
# 在Python3中,__init__方法是当对象创建后,实例化对象自动执行的一种方法,而__new__方法和__init__方法不同,可以通俗的理解__init__方法在__new__方法执行后再执行。
# __new__方法是用来创建对象的,__new__方法需要有一个返回值,这个返回值表示创建出来的对象的引用。__init__方法是刚刚创建出来的对象的应用。
class A:
def __init__(self):
self.x = 1
print('__init__方法,执行了。')
def __del__(self):
print('__del__方法,执行了。')
def __new__(cls, *args, **kwargs):
print('__new__方法,执行了。')
return object.__new__(A)
a = A()
# __new__方法,执行了。
# __init__方法,执行了。
# __del__方法,执行了。
__call__
对象后面加括号,触发执行。
注意:构造方法的执行时由创建对象触发的,即:对象 = 类名();而对于__call__
方法的执行是由对象后加括号触发的。即:对象()或类()()。
class A:
def __init__(self):
print('__init__方法,执行了。')
pass
def __call__(self, *args, **kwargs):
print('__call__方法,执行了。')
a = A() # 执行__init__
a() # 执行__call__
# __init__方法,执行了。
# __call__方法,执行了。
with和__enter__
,__exit__
class A:
def __enter__(self):
print('before')
def __exit__(self, exc_type, exc_val, exc_tb):
print('after')
with A() as a:
print('123')
# with 语句和 init
class A:
def __init__(self):
print('init')
def __enter__(self):
print('before')
def __exit__(self, exc_type, exc_val, exc_tb):
print('after')
with A() as a:
print('123')
# init
# before
# 123
# after
# with 语句和 文件操作
class MyFile:
def __init__(self, path, mode='r', encoding='utf-8'):
self.path = path
self.mode = mode
self.encoding = encoding
def __enter__(self):
self.f = open(self.path, mode=self.mode, encoding=self.encoding)
return self.f
def __exit__(self, exc_type, exc_val, exc_tb):
self.f.close()
with MyFile('file',mode='w') as f:
f.write('dnf')
# 会在当前文件夹内创建一个名为 file 的文件,并写入 dnf
# with 和 pickle
import pickle
class MyPickledump:
def __init__(self, path):
self.path = path
def __enter__(self):
self.f = open(self.path, mode='ab')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.f.close()
with MyPickledump('file') as f:
f.dump({1,2,3,4,5,6})
# 执行以上序列化后再进行以下的反序列化
class MyPickleload:
def __init__(self, path):
self.path = path
def __enter__(self):
self.f = open(self.path, mode='rb')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.f.close()
def load(self):
return pickle.load(self.f)
def loaditer(self):
while True:
try:
yield self.load()
except EOFError:
break
with MyPickleload('file') as f:
for item in f.loaditer():
print(item)
# wint 和 pickle 和 iter
import pickle
class MyPickledump:
def __init__(self,path):
self.path = path
def __enter__(self):
self.f = open(self.path, mode='ab')
return self
def dump(self,content):
pickle.dump(content,self.f)
def __exit__(self, exc_type, exc_val, exc_tb):
self.f.close()
# with MyPickledump('file') as f:
# f.dump({1,2,3,4})
class Mypickleload:
def __init__(self,path):
self.path = path
def __enter__(self):
self.f = open(self.path, mode='rb')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.f.close()
def __iter__(self):
while True:
try:
yield pickle.load(self.f)
except EOFError:
break
with Mypickleload('file') as f:
for item in f:
print(item)
__len__
class A:
def __init__(self):
self.a = 1
self.b = 2
def __len__(self):
return len(self.__dict__)
a = A()
print(len(a))
__hash__
class A:
def __init__(self):
self.a = 1
self.b = 2
def __hash__(self):
return hash(str(self.a)+str(self.b))
a = A()
print(hash(a))
__eq__
class A:
def __init__(self):
self.a = 1
self.b = 2
def __eq__(self,obj):
if self.a == obj.a and self.b == obj.b:
return True
a = A()
b = A()
print(a == b)
# True
千里之行,始于足下。