类中的内置方法

内置方法

一、简单介绍

  • 格式:方法名字()
  • 名称:
    • 类中的内置方法
    • 类中的特殊方法
    • 双下划线方法
    • 魔术方法(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'])
    
    
posted @ 2020-02-06 16:07  大道至诚  阅读(148)  评论(0编辑  收藏  举报