类中的内置方法
内置方法
一、简单介绍
- 格式:方法名字()
- 名称:
- 类中的内置方法
- 类中的特殊方法
- 双下划线方法
- 魔术方法(magic method)
- 以上都是对该方法的描述,使用哪一种都可以
- 类中的每一个双下划线方法都有它自己的特殊意义
二、内置方法类别
一、__call__方法
-
调用格式:
- 第一种方式:直接实例对象加括号,第一种方式是最基本的方式
- 第二种方式:通过把一个类作为参数传递给另外一个类,在init中再把第一个类的实例对象
传递给第二个类的属性,通过属性加括号调用__call__方法,第二种方法在
源码中很常见
-
案例
class A: def __call__(self, *args, **kwargs): print('执行call方法') a = A() a() a.__call__() # 也可以直接调用call方法 # 对象加括号默认执行__call__方法,也可以直接使用A()()来调用 class B: def __init__(self, cls): # 可以在实例化A类之前做一些事情 self.a = cls() # 把一个类的对象作为另外一个类的属性值,就叫组合 # self.a是cls的实例化对象 self.a() # 调用__call__方法 B(A)
二、__len__方法
-
len():用于计算长度或者个数,调用/触发条件是len(obj)
-
案例
class List: def __init__(self, name, age): self.l = [1, 3, 4, 5, 6] self.name = name self.__age = age # def __len__(self): # return len(self.l) def __len__(self): return len(self.__dict__) # 返回类中的属性个数 def __attr__(self): return self.__dict__ # self.__dict__调用的是属性 li = List('李哲', 19) print(len(li)) print(li.__len__()) # 调用时len()和__len__()效果是一致的 # 内置函数的使用必然对一个__名字__的内置方法 print(li.__attr__()) class A: def __init__(self, string): self.__string = string def str(self): return self.__string a = A('123243546576') class Str: def __init__(self, obj): self.string = obj.str() def __len__(self): return len(self.string) a = Str(a) print(len(a))
三、 new()构造方法
-
new():被称为构造方法,用于给实例对象分配空间。新式类中默认没有该方法,如果类中自定义该方法,需要继承自object
类中的__new__()方法再进行设定。 -
单例类:一个类从始至终只有一个实例对象,即只有一个实例对象内存地址,后边的实例对象会把前边的实例对象覆盖掉
通常情况西不设置__new__()方法的类都是多例类,一个实例对象分配一个内存地址。 -
需要注意的是__new__()方法中的参数除了cls外,必须加上*args和**kwargs参数,否则__init__传递不了参数
-
实例对象的过程
- new()在内存中开辟一个空间,属于对象的
- 把对象的空间传递给__init__中的self,执行__init__方法
- 把这个对象的空间返回给调用者,
- new()在实例化对象之后,执行__init__()之前调用,被成为构造方法。
-
案例
'''__new__()构造方法''' class Single1: def __new__(cls, *args, **kwargs): # 注意:这里必须加上*args和**kwargs参数,否则__init__传递不了参数 print("在object类的__new__方法内") obj = super().__new__(cls) # 为对象开辟内存空间,传递cls,不是 return ('在new方法中', obj) # 新式类中没有__new__方法,所以在自定义的类创建自己的__new__方法中调用object类的__new__方法 def __init__(self): print("在Single类的__init__方法内") s = Single1() print(s)
四、str()方法
-
当不设定__str__()时,直接打印实例对象输出的是对象所在的内存地址,因为默认的是继承自object类中的__str__(),
当在类类中自定义__str__()方法后直接打印实例对象输出的是自定义的__str__()中的内容,object中的被覆盖掉了。 -
当print(onj)、%s % obj和print(str(obj))时需要用到__str__()方法
-
调用__str__()的方式是:str(obj), 一般不会直接用obj.str()调用
-
案例
class Student: def __str__(self): return self.name def __init__(self, name): self.name = name s1 = Student('alex') print(s1) # 当类中不定义__str__方法时,只打印s1,打印出来是s1的内存地址,没有具体的内容,因为object中的__str__方法返回的是对象的内存地址 # 当自定义类中定义的__str__方法后,会覆盖掉object中的__str__方法,自定义什么返回值就打印什么返回值 print(str(s1)) # str(obj)想当于执行obj.__str__()方法 print('学生:%s' % str(s1)) # print(str(obj))、%s % obj和print(obj)都需要用到__str__()方法
repr()方法
-
repr()方法是__str__()方法的备胎,如果有__str__()则直接执行,没有__str__()而有__repr__(),则执行__repr__()方法
-
区别:
- str():pycharm中的返回值去掉了引号
- repr():把数据原本的类型显示出来
a = '123' print(str(a)) print(repr(a)) c = '丽丽' print(str(c)) print(repr(c)) ''' 打印结果:123、'123'、丽丽、'丽丽' '''
-
特别需要注意的查找法则:当子类中没有__str__()时,程序会继续往上找,如果除了object以外的父类中有则执行父类中的__str__(),
如果除了object以外的父类中都没有,而子类中有备胎__repr__(),如果子类中没有__repr__(),则往父类中找__repr__(),如果除了
object类以外的父类中都没有__repr__(),则最终执行object中的__str__(),返回相应内容。'''__repr__()''' class A: GENDER = '女' def __init__(self, name): self.name = name def __str__(self): return self.name def __repr__(self): return '*%s*' % self.name class B(A): def __init__(self, name, age): super().__init__(name) self.age = age b = B('李志', 20) print(b) print(str(b)) print(repr(b)) ''' 打印结果:李志、李志、*李志* '''
六、item系列
-
item系列用于处理key和value这种形式的数据,和[]是相关的
-
getitem():用于获取value的值,obj[key]调用该方法
-
setitem():用于存储key、value格式的数据,obj[key] = value调用
-
delitem():用于删除key和value,调用格式必须是del obj[key]
-
当使用一些模块中的特殊方法时要求必须使用item系列才会用到这三种方法
class B: def __getitem__(self, key): value = getattr(self, key) return value # 通过反射key来获取value值,self指的是调用的实例对象 def __setitem__(self, key, value): setattr(self, key, value) # 获取到的值是字符串形式的,在字典中也没有存储key和value # 所以需要用反射设置key和value,等同于self.key = value def __delitem__(self, key): delattr(self, 'key') return '已删除' # 删除key对应的值 b = B() b['key'] = 'value' # 传值,调用__setitem__()方法 print(b['key']) # 取值,调用的是__getitem__()方法 b.name = '李敏镐' print(b.name) # 普通的方法也能实现赋值操作 del b['key'] b['k1'] = 'v1' print(b['k1']) del b['k1'] # 注意:删除操作的是格式必须是del obj[key],否则无法删除 print(b['k1'])