zoukankan      html  css  js  c++  java
  • 元类与魔法方法

    1.isinstances与issubclass

     isinstances作用是判断耨个对象是不是某各类的实例(判断类型)

     issubclass作用是判断一个类是不是另外一个类的子类

     1 class Person:
     2     pass
     3 
     4 class Student(Person):
     5     pass
     6 
     7 stu = Students()
     8 
     9 # 判断stu是不是Student的实例
    10 print(isinstance(stu,Student))
    11 
    12 # 判断Student是都为Person的子类
    13 # 所有类都是object的子类或子子类
    14 print(issubclass(Student,Person))
    isinstance与issubclass

    2.反射

      通过字符串操作属性就是反射

      使用场景:当需要获取一个对象,但是并不清楚对象内部的细节,就需要用到反射

     1 '''
     2   hasattr 是否存在某个属性
     3   getattr 获取某个属性的值
     4   setattr 设置某个属性的值
     5   delattr 删除某个属性
     6 '''
     7 class Student:
     8     def __init__(self,name,sex,age):
     9         self.name = name
    10         self.age = age
    11         self.sex = sex
    12 
    13     def study(self):
    14         print("学生正在学习...")SS
    15 
    16 stu = Student("alan","man",18)
    17 # 当你获取到一个对象 但是并不清楚搞对象的内部细节时  就需要使用反射了
    18 def test(obj):
    19     if hasattr(obj,"name"):
    20         print(getattr(obj,"name","没有name属性"))
    21 test(stu)
    View Code
     1 # 需求:需要编写一个CMD工具,这个工具可以支持两个命令dir ,tasklist
     2 class CMD:
     3     
     4     def dir(self):
     5         print('目录')
     6 
     7     def tasklist(self):
     8         print('任务列表')
     9 
    10 #实例化
    11 cmd = CMD()
    12 
    13 res = input('cmd>>>:').strip()
    14 
    15 if hasattr(cmd,res):
    16     func = getattr(cmd,res)
    17     print(func)
    18     func()
    19 else:
    20     print('CMD命令错误')
    反射练习

    3.__str__

       前后都带下划线的都是特殊内置函数,在某些时机会自动运行,一般不会调用,__str__方法是必须返回一个字符串,返回的是什么,打印的就是什么

     1 class Test:
     2     def __init__(self,name):
     3         self.name = name
     4     def __str__(self):
     5         print("str run....")
     6         return self.name
     7 t = Test("ss")
     8 
     9 print(int(1).__str__())
    10 
    11 # 在将一个对象转换字符串时  本质就是在调用这个对象 __str__方法
    12 print(str(t))
    __str__

    4.__del__

      当程序运行结束需要做一些清理操作时候,需要用到__del__

      __del__也称之为析构函数(分析构造,并拆除这个对象)

    5.exec

      解析执行python代码 并且将得到的名称 存储到制定的名称空间

      exec需要三个参数:第一个参数 需要一个字符串对象,表示需要被执行的python代码

               第二个参数 是一个字典,表示全局名称空间

               第三个参数 也是一个字典,表示局部名称空间

      如果同时制定了 全局和局部 则 会字符串中包含名称 解析后存到局部中

     如果只传了一个传参数 则 将字符串中包含名称 解析后存到全局中

    6.元类

      元类是指用于产生类的类,type就是元类.  所有的自定义类都是通过type实例化得来的

      在创建模块的过程:1.创建一个空的名称空间  2.执行内部代码  3.将得到的名字存入到名称空间

     1 '''
     2 1.类是由type实例化产生的
     3 2.我们可以使用type来产生一个类
     4 3.一个类是由 类名字 类的父类元祖 类的名称空间 三个部分组成
     5 '''
     6 '''
     7 class Test(object): #Test = type("Test",(object,),{})
     8     pass
     9 
    10 '''
    11 ######自定义类
    12 #类的名字
    13 class_name = 'MyClass'
    14 #类的父类们
    15 base_classes = (object,)
    16 #类的名称空间
    17 name_base ={}
    18             
    19 res = type(class_name,base_classes,name_base)
    20 print(res)        
    21     
    自定义类

      使用__call__方法控制对象的创建过程

     1 # 自定义一个元类需要继承type
     2 class MyMeta(type):
     3 
     4     # self表示要创建对象的那个类(Person) *args是调用Person时传入的参数
     5     def __call__(self, *args, **kwargs):
     6         print('this is MyMate call run')
     7         print(self, *args, **kwargs)
     8         # 创建对象
     9         obj = object.__new__(self)
    10         # 调用初始化方法
    11         self.__init__(obj, *args, **kwargs)
    12         # 得到一个完整的对象
    13         return obj
    14 
    15 
    16 # 修改Person类的元类为MyMeta
    17 class Person(metaclass=MyMeta):
    18     def __init__(self, name, age):
    19         self.name = name
    20         self.age = age
    21 
    22     def __call__(self, *args, **kwargs):
    23         print('this is Person call run')
    24 
    25 
    26 # 调用Person这个对象时 执行的是 Person的类(type)中__call__ 方法
    27 p = Person('alan', 25)
    28 print(p)
    __call__

      通过元类控制类的创建过程

     1 # self 刚建出来的类
     2 # 第二个 类的名字
     3 # 第三个 类的父类们 元组
     4 # 第四个 这个类传进来的名称空间
     5 class  MyMeta(type):
     6 
     7     def __init__(self,class_name,bases,namespace):
     8         if not class_name.istitle():
     9             print('类名必须首字母大写')
    10             raise TypeError('类名必须首字母大写')
    11         if not self.__doc__:
    12             print('类中必须包含文档注释')
    13             raise TypeError('类中必须包含文档注释')
    14 
    15 
    16 
    17 class Student1(metaclass=MyMeta):
    18     """
    19     sss
    20     """
    21     def __init__(self,name):
    22         self.name = name
    23 # class Student(metaclass=MyMeta):
    24 #     def __init__(self,name):
    25 #         self.name = name
    26 # 
    27 # class student(metaclass=MyMeta):
    28 #     """
    29 #     sss
    30 #     """
    31 #     def __init__(self,name):
    32 #         self.name = name
    33 
    34 
    35 print(Student1.__doc__)
    36 print(Student1)
    37 # print(Student.__doc__)
    38 # print(student)
    通过元类控制类的创建过程

      单例模式

      一个类如果只有一个实例 那么该类称之为单例

     1 class MyMeta(type):
     2 
     3     obj = None
     4     def __call__(self, *args, **kwargs):
     5         if not MyMeta.obj:
     6             obj = object.__new__(self)
     7             self.__init__(obj,*args,**kwargs)
     8             MyMeta.obj = obj
     9         return MyMeta.obj
    10 
    11 
    12 class  Printer(metaclass=MyMeta):
    13     """
    14     这是一个单例类 请不要直接实例化 使用get方法来获取实例
    15     """
    16 
    17     obj = None
    18     def __init__(self,name,brand,type):
    19         self.name = name
    20         self.brand = brand
    21         self.type = type
    22 
    23     def printing(self,text):
    24         print("正在打印 %s"  % text)
    25 
    26     @classmethod
    27     def get_printer(cls):
    28         if not cls.obj:
    29             obj = cls("ES005","爱普生","彩色打印机")
    30             cls.obj = obj
    31             print("创建了新的对象")
    32 
    33         return cls.obj
    34     
    35 
    36 p1 = Printer("ES005","爱普生","彩色打印机")
    37 p2 = Printer("ES005","爱普生","彩色打印机")
    38 
    39 print(p1)
    40 print(p2)
    单例模式
    学习,学习,学习! 学习是为了更好的未来,不要让别人瞧不起你,加油!!!
  • 相关阅读:
    [转]iOS应用程序多语言本地化解决方案
    【汇】iOS面试题
    [转]UIView 和 CALayer的那点事
    [转]25个增强iOS应用程序性能的提示和技巧 — 高级篇
    [转]25个增强iOS应用程序性能的提示和技巧 — 中级篇
    [转]25个增强iOS应用程序性能的提示和技巧 — 初级篇
    [转]NSNotification、delegate和KVO、KVC的区别
    [转]ViewController的生命周期
    [QualityCenter]设置工作流脚本-设置不同字段值关联不同列表
    [QualityCenter]设置工作流脚本-缺陷字段值发生变化时的处理
  • 原文地址:https://www.cnblogs.com/yangyufeng/p/10145604.html
Copyright © 2011-2022 走看看