zoukankan      html  css  js  c++  java
  • 面向对象知识点3

    面对对象知识点

    isinstance和type的区别

    ​ 当我们创建一个自定义类时,判断数据类型时,isinstance会判断子类即其父类时为True,而type只判断为当前子类。

    class A:
        pass
    class B(A):
        pass
    
    b = B()
    
    #isinstance的应用
    print(isinstance(b,A))  #True
    print(isinstance(b,B))  #True
    
    #type的应用
    print(type(b)==B)   #True
    print(type(b)==A)   #False
    

    反射(自省)

    class A:
        count = 6
    
        def run(self):
            print('run')
    
    f = A()
    
    #1.hasattr(判断类对象是否存在指定方法和属性)
    print(hasattr(f,'count'))   # True
    print(hasattr(f,'run'))     # True
    
    #2.getattr(获得对象的属性和方法)
    print(getattr(f,'count'))   # 6
    getattr(f,'run')()          # run
    
    #3.setattr(修改对象属性)
    setattr(f,'count',5)
    print(getattr(f,'count'))   # 5
    
    #4.delattr(删除对象属性)
    delattr(f,'count')
    

    元类

    ​ 元类:一个造类的过程,元类》》元类实例化( ) = 类》》类》》类实例化( )=对象

    1. type关键字造类
    #第一种形式:type模仿class关键字造类
    1.类名:class_name
    class_name = 'Foo'
    
    2.类体代码:class_body  #把类的属性和方法以字符串形式放入名称空间中
    class_body = '''
    count = 0
    def run(self):
        print('run')'''
    class_dic = dict()
    exec(class_body,{},class_dic) #通过内置方法exec()从字符串变成类体代码
    
    3.基类(父类)
    class_bases = (object,)
    
    创建类成功
    Foo = type(class_name,class_bases,class_dic)
    
    f = Foo()
    print(f.count)	# 0
    
    1. 元类造类:控制造类的过程
    #第二种方式:使用元类造类(控制制造类的过程),通过元类实例化成一个类,事实上还是借助了type
    #元类模板:
    class MyMeta(type):
        def __init__(self,class_name,class_dic,class_bases):
           
        	**控制生成类的条件**
            if class_name.islower():
                raise TypeError('类名必须大写')
            
            super().__init__(class_name,class_dic,class_bases)
     
    #通过metaclass创建类
    class Foo(object,metaclass=MyMeta):
        count = 0
        def run(self):
            print('run')
    
    f= Foo()
    print(f.count)	# 0
    f.run()			# run
    
    
    
    1. 元类造类:控制对象产生的过程
    #元类创建类时控制类的产生,也可以控制对象的产生
    #元类》》元类实例化() = 类的过程:自动触发了__init__方法
    #类实例化()》》=对象的过程:自动触发了__call__的方法
    
    class MyMeta(type):
        #Foo=mymeta()
        def __init__(self,class_name,class_bases,class_dic):
            if class_name.islower():
                raise TypeError('类名需要大写')
            # if not class_dic.get('__doc__'):
            #     raise TypeError('需要加注释')
    
            super().__init__(class_name,class_bases,class_dic)
        
        ## f = Foo() = mymeta()()
        def __call__(self,*args,**kwargs):
    
            for i in args:
                if i.isdigit():
                    raise TypeError('error')
            obj = self.__new__(self)
            self.__init__(obj,*args,**kwargs)
    
    
            return obj
    
    class Foo(object,metaclass=MyMeta):
        def __init__(self,x):
            self.x = x
    x = input('请输入:')
    f = Foo(x)
    print(f.x)
    

    小结:以元类早子类,子类的属性查找顺序:子类实例化对象本身,子类,父类,.....,object类,type元类,找不到即报错。

  • 相关阅读:
    解决IE8不兼容通过class名获取元素的方法
    移动端页面遇到过的各种坑
    强大的正则表达式
    弹性盒子布局
    vue环境搭建
    fullpage.js使用指南
    ES5原生api(1)
    双色球中奖率分析(python)
    使用python脚本的3D引擎Panda3d
    Python lambda介绍
  • 原文地址:https://www.cnblogs.com/bruce123/p/11074658.html
Copyright © 2011-2022 走看看