魔术方法:再不需要程序员定义,本身就存在类中的方法就是魔术方法。
魔术方法通常都长这样:__名字__。
1.__str__和__repr__
为了方便记忆看如下列子
class Course: def __init__(self,name,period,price,teacher): self.name= name self.period = period self.price = price self.teacher = teacher def __str__(self): return ‘str : %s %s %s %s‘ % (self.name, self.period, self.price, self.teacher) def __repr__(self): return ‘repr : %s %s %s %s‘ % (self.name, self.period, self.price, self.teacher) course_lst = [] python = Course(‘python‘,‘6 month‘,29800,‘boss jin‘) course_lst.append(python) linux = Course(‘linux‘,‘5 month‘,25800,‘oldboy‘) course_lst.append(linux) for id,course in enumerate(course_lst,1): # print(‘%s %s %s %s %s‘%(id,course.name,course.period,course.price,course.teacher)) print(id,course) print(‘%s %s‘%(id,course)) print(str(course)) print(repr(course)) print(‘%r‘%course)
__str__,__repr__
__str__触发条件:
1.当你打印一个对象的时候触发
2.当你使用%格式化的时候触发
3.str强转数据类型的时候触发
__repr__:
1.__repr__是__str__的备胎
2.有__str__的时候执行__str__,没有实现__str__的时候,执行__repr__
3.repr(obj)内置函数对应的结果是__repr__的返回值
4.当你使用%r的格式化的时候 触发__repr__
2.__new__
在init之前,实例化对象的第一步是__new__创建了一个空间
class Foo: def __init__(self): # 初始化方法 print(‘执行了init‘) def __new__(cls, *args, **kwargs): # 构造方法 # object.__new__(cls) print(‘执行了new‘) return object.__new__(cls) obj = Foo()
创造一个对象比喻成捏小人
new是把小人捏出来
init给小人穿衣服
应用:创建单例模式
class Foo: __instance = None def __init__(self, name, age): # 初始化方法 self.name = name self.age = age self.lst = [name] def __new__(cls, *args, **kwargs): # 构造方法 if cls.__instance is None: cls.__instance = object.__new__(cls) return cls.__instance obj1 = Foo(‘alex‘, 20) obj2 = Foo(‘egon‘, 22) abc1 = Foo(‘cao‘, 33) print(obj1.lst, obj2.lst, abc1.lst)
单列模式
3.__del__
对象的__del__是对象在被gc消除回收的时候起作用的一个方法,它的执行一般也就意味着对象不能够继续引用。
看如下列子:
class Foo: def __init__(self, name, age): self.name = name self.age = age self.file = open(‘file‘, mode=‘w‘) def write(self): self.file.write(‘sjahgkldhgl‘) def __del__(self): # 析构方法 : 在删除这个类创建的对象的时候会先触发这个方法,再删除对象 # 做一些清理工作,比如说关闭文件,关闭网络的链接,数据库的链接 self.file.close() print(‘执行del了‘) f = Foo(‘alex‘, 20) print(f)
__del__
4.__len__
如果一个类表现得像一个list,要获取有多少个元素,就得用 len() 函数。
要让 len() 函数工作正常,类必须提供一个特殊方法__len__(),它返回元素的个数。
class A: def __init__(self): self.a = 1 self.b = 2 def __len__(self): return len(self.__dict__) a = A() print(len(a)) print(a.__dict__)
菲波那切数列
# 菲波那切数列 # class Fib(object): # def __init__(self, num): # a, b, L = 0, 1, [] # for n in range(num): # L.append(a) # a, b = b, a + b # self.numbers = L # # def __str__(self): # return str(self.numbers) # # # __repr__ = __str__ # # def __len__(self): # return len(self.numbers) # # # f = Fib(10) # print(f) # print(len(f))
菲波那切数列
5.__eq__
__eq__ 当判断两个对象的值是否相等时,触发此方法.
class Staff: def __init__(self,name,sex): self.name = name self.sex = sex def __eq__(self, other): return self.__dict__ == other.__dict__ alex = Staff(‘alex‘,‘不详‘) alex2 = Staff(‘alex‘,‘不详‘) alex22 = Staff(‘alex2‘,‘female‘) print(alex == alex2) # alex.__eq__(alex2) print(alex2 == alex22)
6.__call__
对象后面加括号,触发执行。
class Foo: def __init__(self): pass def __call__(self, *args, **kwargs): print(‘__call__‘) obj = Foo() # 执行 __init__ obj() # 执行 __call__
7.__hash__
# 当一个对象的类中有"__hash__"这个方法时, 那么这个对象就可以执哈希计算
# 前提是要哈希的值是可哈希的. 哈希的不是对象, 而是可以通过对象直接执行"hash(obj)"
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))
8.item系列
__getitem__,__setitem,__delitem__
class Foo: def __init__(self,name): self.name=name def __getitem__(self, item): print(self.__dict__[item]) def __setitem__(self, key, value): self.__dict__[key]=value def __delitem__(self, key): print(‘del obj[key]时,我执行‘) self.__dict__.pop(key) def __delattr__(self, item): print(‘del obj.key时,我执行‘) self.__dict__.pop(item) f1=Foo(‘sb‘) f1[‘age‘]=18 f1[‘age1‘]=19 del f1.age1 del f1[‘age‘] f1[‘name‘]=‘alex‘ print(f1.__dict__)
item系列
原文地址:https://www.cnblogs.com/caoshitong/p/10260460.html