赞
踩
__new__
方法用于产生实例化对象(空属性),在创建实例对象的时候调用。重写__new__
方法可以控制对象的产生过程,在单例模式中起很大作用。
__init__
方法是初始化方法,负责对实例化对象进行属性值初始化,重写__init__
方法可以控制对象的初始化过程。
__init__
没有返回值,__new__
方法必须返回一个对象。
class A(object): def __init__(self): print("调用__init__") def __new__(cls, *args, **kwargs): print("调用__new__") return super(A, cls).__new__(cls, *args, **kwargs) if __name__ == '__main__': s = A() # 输出结果 # 调用__new__ # 调用__init__
单例模式:
class Single(object): def __new__(cls, *args, **kwargs): if not hasattr(cls, '_instance'): cls._instance = super(Single, cls).__new__(cls) return cls._instance class A(Single): def __init__(self): pass a = A() b = A() print(id(a)) # 4347816720 print(id(b)) # 4347816720
两者的目的都是为了显式的显示对象的一些必要信息,方便查看和调试。__str__
被print默认调用,__repr__
被控制台输出时默认调用。即,使用__str__
控制用户展示,使用__repr__
控制调试展示。
class A(object): def __str__(self): return "class A" if __name__ == '__main__': s = A() print(s) # 输出结果 # class A class A(object): def __init__(self): self.a = 12 if __name__ == '__main__': s = A() print(s) # 默认调用object的__repr__方法 # 输出结果 # <__main__.A object at 0x108dc6910> # 重写repr方法与str,效果与str一样,同时重写的话print调用__str__ class A(object): def __init__(self): self.a = 12 def __repr__(self): return "pppppp" if __name__ == '__main__': s = A() print(s) # 输出结果 # pppppp
__call__
方法提供给对象可以像函数那样被执行的能力。在类装饰器中有很大作用。
class A(object): def __call__(self, *args, **kwargs): print(args) print(kwargs) return "__call__被执行了" if __name__ == '__main__': s = A() print(s(1, 2, 3, a=11, b=33)) # 输出结果 # (1, 2, 3) # {'a': 11, 'b': 33} # __call__被执行了
类装饰器:
class B(object): def __init__(self, *args, **kwargs): print("__init__") print(args) print(kwargs) print("__init__") def __call__(self, func): print("__call__") def inner(*args, **kwargs): print(args) print(kwargs) return func(*args, **kwargs) return inner @B('xiaowang', age=12) def hello(name, age=15): print("hello") print(name) print(age) print("hello") hello('laowang', age=16) # 输出: # __init__ # ('xiaowang',) # {'age': 12} # __init__ # __call__ # ('laowang',) # {'age': 16} # hello2 # laowang # 16 # hello2
__del__
用于当对象的引用计数为0时自动调用。
__del__
一般出现在两个地方:1、手工使用del减少对象引用计数至0,被垃圾回收处理时调用。2、程序结束时调用。
__del__
一般用于需要声明在对象被删除前需要处理的资源回收操作。
class A(object): def __del__(self): print("类A的对象被删除了") class B(object): def __del__(self): print("类B的对象被删除了") if __name__ == '__main__': a = A() b = B() del b # 输出结果 # 类B的对象被删除了 # 类A的对象被删除了
这2个方法用于将一个对象模拟成序列。重写这两个方法就可以实现自定义的迭代对象。
__next__实现斐波那契生成器函数
import sys def fibonacci(n): # 生成器函数 - 斐波那契 a, b, counter = 0, 1, 0 while True: if counter > n: return yield a a, b = b, a + b counter += 1 if __name__ == '__main__': f = fibonacci(10) # f 是一个迭代器,由生成器返回生成 while True: try: print(next(f), end=" ") except StopIteration: sys.exit() # 0 1 1 2 3 5 8 13 21 34 55
自定义迭代器
class MyNumbers(object): def __iter__(self): self.a = 1 return self def __next__(self): if self.a <= 20: b, self.a = self.a, self.a + 1 return b else: raise StopIteration if __name__ == '__main__': # 实例化自定义迭代器 myclass = MyNumbers() # 创建迭代器对象 myiter = iter(myclass) for i in myiter: print(i, end=" ") # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
__getitem__(self, key)
这个方法应返回与指定键相关联的值。对序列来说,键整数(也可以是负数),对映射来说,键可以是任何类型。
__setitem__(self, key,value)
:这个方法应以与键相关联的方式存储值,以便以后能够使用__getitem__
来获取。
__delitem__(self, key)
:这个方法在对对象的组成部分使用__del__
语句时被调用,应删除与key相关联的值。
class A(object): def __init__(self, name, age): self.name = name self.age = age self.stu = {name: age} def __getitem__(self, item): return self.stu.get(item) def __setitem__(self, key, value): self.stu[key] = value def __delitem__(self, key): del self.stu[key] if __name__ == '__main__': a = A('XiaoWang', 12) print(a.stu) # {'XiaoWang': 12} print(a['XiaoWang']) # 12 a['LaoWang'] = 54 print(a.stu) # {'XiaoWang': 12, 'LaoWang': 54} del a['XiaoWang'] print(a.stu) # {'LaoWang': 54}
当使用obj.x = y的时候触发对象的setattr方法,当del obj.x的时候触发对象的delattr方法。
当尝试访问对象的一个不存在的属性时会触发getattr方法,可以重写这3个方法来控制对象属性的访问、设置和删除。
class A(object): def __init__(self, name, age): self.name = name self.age = age def __getattr__(self, item): return "%s属性不存在!" % item def __setattr__(self, key, value): print("设置%s属性的值为%s" % (key, value)) super(A, self).__setattr__(key, value) def __delattr__(self, item): print("删除属性%s" % item) super(A, self).__delattr__(item) if __name__ == '__main__': a = A('XiaoWang', 12) # 设置name属性的值为XiaoWang # 设置age属性的值为12 print(a.height) # height属性不存在! a.age = 99 # 设置age属性的值为99 del a.name # 删除属性name
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。