zoukankan      html  css  js  c++  java
  • 面向对象 几个内置方法

    首先class类里的内置方法,比如:__call__,__str__这些都是在一定条件下自动运行的。

    下面我们来介绍几个内置方法

    1、__str__   #先讲讲他的作用,在print打印对象的时候会自动触发运行

    #例子1:
    class Student:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
    
    stu1 = Student('zhuyu',19)
    print(stu1)      #运行原理就是,先在Student类里找__str__方法,没有就去他的父类找
    print(object.__str__(stu1))   #验证了Student的父类里面有__str__方法
    
    #输出结果是:
    #<__main__.Student object at 0x0000023A1170C128>
    #<__main__.Student object at 0x0000023A1170C128>
    
    #例子2:
    #    我们可以在Student类自己定义一个__str__方法来验证,执行print打印操作,原理#是执行了__str__方法的
    class Student:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def __str__(self):
            print(self.name)
            return '<name:%s age:%s>' %(self.name,self.age)
    
    stu1 = Student('zhuyu',19)
    print(stu1)     #这个stu1就是__str__的返回值
    #输入结果是:
    #zhuyu
    #<name:zhuyu age:19>
    #补充一下,对象的查找属性的顺序:对象自己的名称空间,对象对应类的名称空间,该类的基类的名称空间

    2、__del__方法   #作用是,会在删除对象之前自动触发该方法

    #我就直接上代码吧
    class Student:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __del__(self):
            print('%s 已经被删除' % self.name)
    
    
    stu1 = Student('zhuyu', 19)
    stu2 = Student('zhanghao', 19)
    print('')
    #他的执行结果是
    #
    #zhuyu 已经被删除
    #zhanghao 已经被删除
    
    ###讲讲为什么是这个输出结果:这个python解释器的垃圾回收机制吧,一个程序运行完毕,python会回收该程序在内存中产生的数据,当执行到print('主'),
    ###后面没有代码执行了,就会删掉stu1,stu2这两个对象,删除这两个对象之前呢,会执行__del__方法,所以会出现上面的结果。

    3、__call__     #在调用该对象时,也就是实例化的时候,会自动运行其类和类的基类中的__call__方法,如果没有的,那么该对象是不可调用的对象

    class Student:   #补充:class Student: 相当于就是 Student = type(类名,该类的基类们,类体代码产生的名称空间)
        pass
    
    Student()
    
    ## 分析一下:首先一切皆对象,Student就是一个对象,Student他是通过元类(type)实例化得来的,所以说调用Student(),就是去找type元类中
    #  找__call__方法去执行,很明显type类中有__call__方法,运行上面那段代码,不会出错。

    # 下面举个例子来验证下上面的结论
    class Student: # (相当于上面例子的type)
    def __init__(self, name, age):
    self.name = name
    self.age = age


    stu1 = Student('zhuyu', 19) # stu1(相当于上面例子的Student)
    try: # 这里我们通过捕捉异常来打印出错原因
    stu1() # 这里相当于上面Student()
    except Exception as e:
    print(e)
    # 打印结果是:'Student' object is not callable
    # “Student”对象不可调用,也就是stu1是不可调用的

    ###结论:通过这两个例子可以得到,只要该对象的类中有__call__方法,那该对象就可以调用,也就是实例化。
    ###该对象实例化,就是运行其类中的__call__方法


    ###验证下:该对象实例化,就是运行其类中的__call__方法
    class Teacher:
    def __init__(self, name):
    self.name = name

    def __call__(self, *args, **kwargs):
    print('我被%s调用了' % self.name)


    tea1 = Teacher('zhuyu')
    tea1()
    #输出结果是:我被zhuyu调用了

    ###如何通过元类来控制类的调用
    #通过在自定义元类里的__call__方法,来实现对类的调用控制
    #1、首先类的调用原理就是运行元类里的__call__方法
    #2、通过__call__方法来实现对对象的初始化操作
    class Mymeta(type):
    def __call__(self, *args, **kwargs): # self就是Student *args和**kwargs就是Student后面的参数
    # print(self)
    # print(args)
    # print(kwargs)
    obj = self.__new__(self) # 就是创建一个Student的空对象
    self.__init__(obj, *args, **kwargs) # 执行__init__方法 这里需要注意查找顺序
    return obj # 将实例化完的对象返回回去


    class Student(object, metaclass=Mymeta):
    def __init__(self, name, age):
    self.name = name
    self.age = age


    stu1 = Student('zhuyu', age=19)
    print(type(stu1),stu1.__dict__)

    这就是类的实例化的整个过程,不过这是我们通过自定义元类来控制类的调用,也就是再__call__多些代码而已
    在默认元类type里,肯定有__call__方法,该方法下面就是产生个空对象,再执行__init__方法



    先讲到这三个方法,其他那些__dict__,__class__,__name__这些就不说了

  • 相关阅读:
    javaweb基础(33)_jdbc的crud操作
    javaweb基础(32)_jdbc学习入门
    javaweb基础(31)_国际化(i18n)
    javaweb基础(30)_EL函数库
    javaweb基础(29)_EL表达式
    javaweb基础(28)_jstl的核心标签
    javaweb基础(27)_jsp标签库实例
    javaweb基础(26)_jsp标签库开发二
    javaweb基础(25)_jsp标签实例一
    选择之难
  • 原文地址:https://www.cnblogs.com/zhuchunyu/p/9442185.html
Copyright © 2011-2022 走看看