zoukankan      html  css  js  c++  java
  • python之路--day23--面向对象高级

    内置函数补充:

      isinstance:判断对象是不是类的实例

      issubclass:判断类是否是一个类的子类

    1,反射

       指程序可以访问,检测,修改它本身状态或行为的一种能力(自省)

     1.1,python面向对象中的反射:通过字符串的形式操作对象相关的属性

      1.1.1  四个可以实现自省的函数

        

    hasattr(object,name)
    判断object中有没有一个name字符串对应的方法或属性,返回布尔值
    
    class test():
        name = 'egon'
        def run(self):
            return 'Helloword'
    
    t = teat()
    
    print(hasattr(t,'run')) 
    True
    
    print(hasattr(t,'Helloword'))
    False
     
    hasattr(object,name)
    class teat():
        name = 'egon'
        def run(self):
            return 'helloword'
    
    t= test()
    getattr(t,'name') #获取name属性。存在就打印出来
    
    getattr(t,'run') #获取run方法,存在就打印方法的内存地址,,加括号可以直接运行
    
    getattr(t,‘age’) #获取一个不存在的属性。报错
    
    
    getattr(t,'age','18')  #若属性不存在,返回一个默认值
    getattr(object,name[,default])
    给对象的属性赋值,若属性不存在,就先创建在赋值
    class test():
        name="xiaohua"
        def run(self):
              return "HelloWord"
    
    t=test()
    
    hasattr(t,'age'#判断属性是否存在
    
    setattr(t,'age','18') #为属性赋值,没有返回值
    
    hasattr(t,'age')#属性存在了
    setattr(object,name,values)
    删除object的属性,name对应的属性不存在就报错
    delattr(object,name)
    class Foo(object):
        staticField = "old boy"
    
        def __init__(self):
            self.name = 'wupeiqi'
    
        def func(self):
            return 'func'
    
        @staticmethod
        def bar():
            return 'bar'
    
    
    print(getattr(Foo, 'staticField'))
    print(getattr(Foo, 'func'))
    print(getattr(Foo, 'bar'))
    类也是对象

    2.__str__方法

       print一个类的实例化对象的时候,会执行类下的__str__函数属性

       这个方法必须有一个返回值

    def People:
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
        def __str__(self):
            return '<名字:%s 年龄:%s 性别: %s>
    %(self.name,self.age,self.sex)
    __str__方法

      

    3.__del__方法

      在一个类的对象被删除的条件下,类下的__del__方法会自动执行

      一般用在程序使用完申请的系统资源之后,释放系统资源

    class People:
        def __init__(self,name.age,sex):
            self.name= name
            self.age=age
            self.sex=sex 
        def __del__(self): #在对象被删除的条件下,自动执行
            print('__del__')
    __del__方法

    4.exec方法

      exec(object,global,local)

      object --字符串形式的命令

      global--全局作用域,字典形式--存放object内定义的全局名称

      local---局部作用域,字典形式--存放object内定义的局部名称

      

    #可以把exec命令的执行当成是一个函数的执行,会将执行期间产生的名字存放于局部名称空间中--前提是被指定为全局名称
    g={
        'x':1,
        'y':2
    }
    l={}
    
    exec('''
    global x,z
    x=100
    z=200
    
    m=300
    ''',g,l)
    
    print(g) #{'x': 100, 'y': 2,'z':200,......}
    print(l) #{'m': 300}
    exec()

    5.元类

      概念理解:

          python中一切都是对象。类本身也是对象。使用class关键字时,python解释器在加载class时创建一个对象(指的是类,而不是类的实例),所以类也是对象,所以:    

    • 把类赋值给一个变量

    • 把类作为函数参数进行传递

    • 把类作为函数的返回值

    • 把类作为容器类型的元素
    class Foo:
        pass
    
    f1 = Foo()#f1是用过Foo类实例化的对象
    
    #type函数可以查看类型,也可以用来查看对象的类
    print(type(f1)) # 输出:<class '__main__.Foo'>     表示,obj 对象由Foo类创建
     print(type(Foo)) # 输出:<type 'type'>  
    查看一个类的类型

    5.1 什么是元类

      元类就是类的类

      type是python的一个内建元类,用来直接控制生成类,python中任何class定义的类都是type实例化的对象

    5.2创建类的两种方式

      1,使用class关键字

      2, 手动模拟class创建类的过程:将创建类的步骤拆分开,手动去创建

      概念理解:

        类的三要素:1.类名----class_name = 'chinses'

              2.类的父类----class_bases = (object,)

              3.执行类体代码产生的名字---class_dic

                  class_body (类体代码使用字符串表示,调用exec方法,得到类体内的名称---没有指定都是局部名称)

    """
    country='China'
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def talk(self):
        print('%s is talking' %self.name)
    """
    class_body

         步骤:1,处理类体代码得到名称空间

           2,调用元类type(元类可以自定义)来产生类chinese

    Foo=type(class_name,class_bases,class_dic) 

    #实例化type得到对象Foo,即我们用class定义的类Foo print(Foo) print(type(Foo)) print(isinstance(Foo,type)) ''' <class '__main__.Chinese'> <class 'type'> True '''

     5.3 自定义元类控制类的调用

      知识储备:__call__,调用对象,会自动触发对象的绑定方法__call__的执行

    class Foo:
        def __call__(self,*args,**keargs):
            print('__call__',args,kwargs)
    
    #调用对象,会自动触发对象下的绑定方法__call__的执行
    #然后将对象本身当做第一个参数传给self,将调用对象时括号内的值传给*args和**kwargs
    __call__方法

     5.3.1  自定义元类:

      步骤1,定义元类,控制类的创建  

    Foo=type(class_name,class_bases,class_dic) 
    #实例化type得到对象Foo,即我们用class定义的类Foo
    #上述表达式  等价于 class Foo
    
    class Mymeta(type):  #继承默认元类的属性
        def __init__(self,class_name,class_bases,class_dic):
            #定制类的创建规则
            if "__doc__" not in class_dic or not class_dic.get('__doc__'):
                raise TypeError('必须为类指定文档注释')
            if not class_name.istitle():
                raise TypeError('类首字母必须大写')
    
            super(Mymeta,self).__init__(class_name,class_bases,class_dic)
            #继承type的代码
     步骤2,__call__方法的知识。
        
    class People(object,metaclass=type):
        def __init__(self,name,age):
            self.name=name
            self.age=age
    
        def __call__(self, *args, **kwargs):
            print(self,args,kwargs)
    
    
    # 调用类People,并不会出发__call__
    obj=People('egon',18)
    
    # 调用对象obj(1,2,3,a=1,b=2,c=3),才会触发对象的绑定方法obj.__call__(1,2,3,a=1,b=2,c=3)
    obj(1,2,3,a=1,b=2,c=3) #打印:<__main__.People object at 0x10076dd30> (1, 2, 3) {'a': 1, 'b': 2, 'c': 3}
    
    #总结:如果说类People是元类type的实例,那么在元类type内肯定也有一个__call__,会在调用People('egon',18)时触发执行,然后返回一个初始化好了的对象obj
    
    
    
    步骤3,自定义元类,控制类的调用(实例化)的过程
    class Mymeta(type):  #继承默认元类的属性
        def __init__(self,class_name,class_bases,class_dic):
            #定制类的创建规则
            if "__doc__" not in class_dic or not class_dic.get('__doc__'):
                raise TypeError('必须为类指定文档注释')
            if not class_name.istitle():
                raise TypeError('类首字母必须大写')
    
            super(Mymeta,self).__init__(class_name,class_bases,class_dic)
            #继承type的代码
    
        def __call__(self, *args, **kwargs):
            #1,实例化People,产生空对象obj
            obj = object.__new__(self)
            #2,调用People下的函数__init__,初始化obj
            self.__init__(obj,*args,**kwargs)
            #3,返回初始化之后的obj
            return obj
    
    

    单例模式

      指的是同一个类实例多长的结果指向同一个对象,用于节省内存空间

    如果我们从配置文件中读取配置来进行实例化,在配置相同的情况下,就没有必要重复产生对象浪费内存

    
    
    #settings.py文件内容如下
    HOST='1.1.1.1'
    PORT=3306
    
    import setting
    class Mysql:
        __instance = None
        def __init__(self,host,port):
            self.host = host
            self.port = port
    
        @classmethod
        def singleton(cls):
            if not cls.__instance:
                cls.__instance = cls(setting.HOST,setting.PORT)#产生一个实例化对象
            return cls.__instance
    
    obj1=Mysql('1.1.1.2',3306)
    obj2=Mysql('1.1.1.3',3307)
    print(obj1 is obj2) #False
    
    obj3=Mysql.singleton()
    obj4=Mysql.singleton()
    print(obj3 is obj4) #True
    不依赖元类的单例模式
    
    
    
     

     

            

  • 相关阅读:
    Linux Ubuntu 忘记用户名和密码 解决办法
    C语言中标准输入流、标准输出流、标准错误输出流
    递归实现字符串反转char* reverse(char* str)合集
    (转)最好的求平方根的方法(精确度VS速度)Best Square Root Method Algorithm Function (Precision VS Speed)
    java验证码识别4
    互聯網產品設計主題詞表
    java验证码识别3
    C++实现C#的get,set属性操作
    简陋,山寨,Everything,桌面搜索,原理,源码
    java验证码识别1
  • 原文地址:https://www.cnblogs.com/guodengjian/p/8857853.html
Copyright © 2011-2022 走看看