一:__str__(self)与__repr__(self)

实例化一个对象,通过打印对象,看到的只是对象的信息,对用户来说显示的信息并不友好,通过__str__(self)或者__repr__(self)来提示一些信息。__repr__(self)是__str__(self)的一个备胎。在print('%r'%对象)用__repr__(self)。

 1 #_*_coding:utf-8_*_
 2 
 3 format_dict={
 4     'nat':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型
 5     'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址
 6     'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名
 7 }
 8 class School:
 9     def __init__(self,name,addr,type):
10         self.name=name
11         self.addr=addr
12         self.type=type
13 
14     def __repr__(self):
15         return 'School(%s,%s)' %(self.name,self.addr)
16     def __str__(self):
17         return '(%s,%s)' %(self.name,self.addr)
18 
19     def __format__(self, format_spec):
20         # if format_spec
21         if not format_spec or format_spec not in format_dict:
22             format_spec='nat'
23         fmt=format_dict[format_spec]
24         return fmt.format(obj=self)
25 
26 s1=School('oldboy1','北京','私立')
27 print('from repr: ',repr(s1))
28 print('from str: ',str(s1))
29 print(s1)
30 
31 '''
32 str函数或者print函数--->obj.__str__()
33 repr或者交互式解释器--->obj.__repr__()
34 如果__str__没有被定义,那么就会使用__repr__来代替输出
35 注意:这俩方法的返回值必须是字符串,否则抛出异常
36 '''
37 print(format(s1,'nat'))
38 print(format(s1,'tna'))
39 print(format(s1,'tan'))
40 print(format(s1,'asfdasdffd'))

二:__del__

析构方法,当对象在内存中被释放时,自动触发执行。

注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

三:item系列

__getitem__方法直接用对象的名字加[]来访问列表。可以直接直接用对象加[]来取值

1 class Foo:
2     def __init__(self):
3         self.l = [1,2,3]
      #self.name = 'egon'
      #self.age = 73
4 5 def __getitem__(self,item): 6 return self.l[item]
      #return self.__dict__[item]
7 f = Foo() 8 print(f[0]) 9 print(f[1])
 #print(f['name'])

__setitem__可以修改__getitem__基础上可以修改对象属性的值

 1 class Foo:
 2      def __init__(self):
 3          self.l = [1,2,3]
 4    self.name = 'egon'
 5    self.age = 73
 6  
 7      def __getitem__(self,item):
 8         return self.l[item]
 9       return self.__dict__[item]  
10 
11     def __setitem__(self,key,value):
12         #print(key,value)
13         self.__dict__[key] = value
14 f = Foo()
15 
16 print(f['name']) 
17 f['name'] = 'alex'
18 print(f.name)   

__delitem__,传一个参数,可以直接删除

 class Foo:
      def __init__(self):
          self.l = [1,2,3]
    self.name = 'egon'
    self.age = 73
  
      def __getitem__(self,item):
         return self.l[item]
       return self.__dict__[item]  
 
     def __setitem__(self,key,value):
         #print(key,value)
         self.__dict__[key] = value

    def __delitem__(self,key):
        del self.__dict__[key]
 f = Foo()
 
 print(f['name']) 
 f['name'] = 'alex'
del f['name']
 print(f.name)  

四:__new__

创建对象时执行__init__,但之前会执行__new__

实现单例模式:

1 class A:
2     def __new__(cls, *args, **kwargs):
3         if not hasattr(cls,'_instance'):
4             cls._instance = object.__new__(cls,*args,**kwargs)
5         return cls._instance
6 
7 one = A()
8 two = A()

五:__call__对象加()执行

1 class Foo:
2     def __call__(self, *args, **kwargs):
3         print(123)
4 
5 f = Foo()
6 f()

六:__len__

一般对象不可以直接调用len()定以后可以用也可以返回其他值

1 class Foo:
2     def __init__(self):
3         self.name = 'lugang'
4         self.age = 23
5     def __len__(self):
6         return len(self.__dict__)
7 
8 f = Foo()
9 print(len(f))

 七:__eq__

实现之后就会按照我定义的方式来判断是否相等

1 class A:
2     def __eq__(self, other):
3         return True
4 
5 a = A()
6 b = A()
7 print(a == b)

八:面试题

对类的对象进行去重

 1 class Person:
 2     def __init__(self,name,age,sex):
 3         self.name = name
 4         self.age = age
 5         self.sex = sex
 6 
 7     def __hash__(self):
 8         return hash(self.name+self.sex)
 9 
10     def __eq__(self, other):
11         if self.name == other.name and self.sex == other.sex:return True
12 
13 p_lst = []
14 for i in range(84):
15     p_lst.append(Person('egon',i,'male'))
16 
17 print(p_lst)
18 print(set(p_lst))