面向对象知识点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元类,找不到即报错。

posted @ 2019-06-23 22:21  wanjiang  阅读(120)  评论(0编辑  收藏  举报