• 反射,元类


    内置函数

    # class Foo:
    #     pass
    # obj=Foo
    # print(isinstance(obj,Foo))
    #在python3中统一类与类型的概念
    #d={"x":1}#d=dict({"x":1})
    
    #print(type(d) is dict)
    # print(isinstance(d,dict))
    isinstance(对象名,类名) 判断是否是实列
    
    # issubclass(子类,父类) 判断一个类是不是另一个类的子类
    
    # class Parent:
    #     pass
    # class Sub(Parent):
    #     pass
    # print(issubclass(Sub,Parent))
    # print(issubclass(Parent,object))
    内置函数

    反射

    1、什么是反射
    通过字符串来操作类或者对象的属性

    2、如何用
    hasattr
    getattr
    setattr
    delattr

    class People:
        country="China"
        def __init__(self,name):
            self.name=name
        def eat(self):
            print("%s is eating" %self.name)
    
    peo1=People("egon")
    print(hasattr(peo1,"eat"))#查看peo1有没有eat属性 #属性需要加引号,底层原理就是依次判断从对象空间->子类->父类里面是否存在eat
    print(getattr(peo1,"eat"))#在又的情况下,用get拿出peo1中的eat,相当于打印peo1.get
    print(getattr(peo1,"XXXX","None"))#在找不到这个属性的时候返回None
    
    setattr(peo1,"age",18)#peo1.age=18 #修改属性
    print(peo1.age)
    print(peo1.__dict__)
    delattr(peo1,"name")#del peo1.name #删除属性
    print(peo1.__dict__)
    class Ftp:
        def __init__(self,ip,port):
            self.ip=ip
            self.port=port
        def get(self):
            print("GET function")
    
        def put(self):
            print("PUT function")
    
        def run(self):
            while True:
                choice = input(">>:").strip()
                # print(choice,type(choice))
                # if hasattr(self,choice):#self是对象conn,#先判断输入的内容是否存在
                #     method=getattr(self,choice)#存在就获取相应功能
                #     method()#调用
                # else:
                #     print("输入的命令不存在")
    
                method = getattr(self,choice,None)
                if method is None:
                    print("输入的命令不存在")
                else:
                    method()
    conn=Ftp("1.1.1",23)
    conn.run()
    反射应用
    # __str__方法
    # class Foo:
    #     pass
    # obj=Foo()#与d={"x":1}一样
    # print(obj)#与print(d)一样,只是obj打印出来是内存地址,d是肉眼能看见的内容
    # class People:
    #     def __init__(self,name,age):
    #         self.name=name
    #         self.age=age
    #      #在对象self被打印时,自动触发,应该是打印该方法内采集与对象相关的信息,然后拼接成字符串返回
    #     def __str__(self):
    #         return"<name:%s age:%s>" %(self.name,self.age) #必须返回的是字符串
    #
    # obj = People("egon",18)
    # obj1=People("yf",17)
    # print(obj)#打印对象时触发__str__
    # print(obj1)
    #__def__格式分析构建方法
    #会在对象被删除之前自动触发,文件关闭操作系统可以用到
    class People:
        def __init__(self,name,age):
            self.name=name
            self.age=age
            # self.f=open("a.txt","wt",encoding="utf-8")
    
        def __del__(self):#程序结束之前自动回收操作系统资源,即文件使用时候用
            print("is")#显示运行标记
            # self.f.close() #达到程序运行结束前回收操作系统资源
    obj=People("yf",17)
    print(obj)
    del obj
    print("ting")

    1、什么是元类
    在python中一切皆对象,那么我们用class关键字定义的类本身也是一个对象
    负责产生该对象的类称之为元类,即元类可以简称为类的类

    class Foo: # Foo=元类() 调用类的类是元类
    pass
    2、为何要用元类
    元类是负责产生类的,所以我们学习元类或者自定义元类的目的
    是为了控制类的产生过程,还可以控制对象的产生过程

    3、如何用元类

    #1、储备知识:内置函数exec的用法
    
    #全局的名称空间 出了内置的名称空间还有文件执行过程中产生的#print(globals())可以查看全局的名称空间内名字
    # class_name="People"
    # class_bases=(object,)
    # class_dic={} #exec运行时会将运行中的产生的名字都丢入岛class_dic的名称空间内,类名称空间
    # class_body=""" #exec提取这里面的代码并且运行,模拟python代码的运行过程
    # country='China'
    # def __init__(self,name,age):
    #     self.name=name
    #     self.age=age
    #
    # def eat(self):
    #     print('%s is eating' %self.name)

    #类名,全局名称空间,类名称空间
    # exec(class_body,{},class_dic)#模拟python代码的运行过程,会将运行中的代码名字都丢入岛class_dic的名称空间内
    #exec中间的括号内是代表全局的名称空间,模拟类定义阶段定义名称空降操作,讲类定义是的名字丢入到类的名称空间
    # People1=type(class_name,class_bases,class_dic)#元类调用赋值给类
    # print(People1)#类

    #创建类的方式有两种,一种是用class关键字创建,另一种是自定义元类
    # 大前提:如果说类也是对象的化,那么用class关键字的去创建类的过程也是一个实例化的过程
    # 该实例化的目的是为了得到一个类,调用的是元类
    #默认的元类是type,专门产生类用的 #class People: #People=type(类名,父类,类的名称空间)
    #创建类的三大要数,类名,父类,类的名称空间

    # class_name='People' #类名
    # class_bases=(object,) #父类,元组显示在名称空间内
    # class_dic={}#类的字典
    # class_body=""" #类体代码
    # country='China'
    # def __init__(self,name,age):
    #     self.name=name
    #     self.age=age
    #
    # def eat(self):
    #     print('%s is eating' %self.name)
    # """
    # exec(class_body,{},class_dic)
    
    # 准备好创建类的三要素
    # print(class_name) #类名
    # print(class_bases) #父类
    # print(class_dic) #类名称空间
    #自定义元类
    # class Mymeta(type):#不继承type就是一个普通的类
    #     def __init__(self,class_name,class_bases,class_dic):
    #         print(self)#本体是People
    #         print(class_name)
    #         print(class_bases)
    #         print(class_dic)
    #         super(Mymeta,self).__init__(class_name,class_bases,class_dic)#重用父类功能
    
    # 分析用class自定义类的运行原理(而非元类的的运行原理):
    #1、拿到一个字符串格式的类名class_name='People'
    #2、拿到一个类的基类们class_bases=(obejct,)
    #3、执行类体代码,拿到一个类的名称空间class_dic={...}
    #4、调用People=type(class_name,class_bases,class_dic)
    
    class Mymeta(type):
        def __init__(self,class_name,class_bases,class_dic):#将元类的格式写入,self是自己建的类
            if class_dic.get("__doc__") is None or len(class_dic.get("__doc__").strip()) == 0:
                raise TypeError("类中必须又文档注释,并且这档注释不能为空")#控制类的名称空间内容
            if not class_name.istitle():
                raise TypeError("类名首字母必须大写")#控制类的名字情况
            super(Mymeta,self).__init__(class_name,class_bases,class_dic) #讲父类的内容传入方式设置,重用父类功能
    
    class People(object,metaclass=Mymeta):#People=Mymeta(类名,基类们,类的名称空间)#完成类的实例化
    #定义类的时候会创造空对象,将空对象连同括号内参数一同传给元类的init内
        """你好,China"""
        country="China"
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def eat(self):
            print("%s is eating" %self.name)
    自定义类
  • 相关阅读:
    BZOJ4827: [Hnoi2017]礼物(FFT 二次函数)
    洛谷P3586 [POI2015]LOG(贪心 权值线段树)
    BZOJ4373: 算术天才⑨与等差数列(线段树 hash?)
    cf711D. Directed Roads(环)
    洛谷P3313 [SDOI2014]旅行(树链剖分 动态开节点线段树)
    洛谷P2045 方格取数加强版(费用流)
    cf900D. Unusual Sequences(容斥 莫比乌斯反演)
    agc007D
    hdu 4287Intelligent IME(简单hash)
    Python Post and Get 登陆web后台系统并抓取页面
  • 原文地址:https://www.cnblogs.com/yf18767106368/p/9248958.html
Copyright © 2020-2023  润新知