instance :判断两个对象是不是一类
issubclass :判断某个类是不是另一个类的子类
#两个常用方法的使用 class Person: pass class Student(Person): pass stu = Student() print(isinstance(stu, Student)) print(issubclass(Student,Person)) True True ##输出的结果是布尔值。
2.反射
反射,其实就是反省。简单来讲就是对象要具备一种修正错误的能力。
#四种方法: hasattr #判断是否存在属性 getattr #获取某个属性的值 setattr #设置某个属性的值 delattr #删除某个属性 #这四种方法的共同点,都是通过字符串来操作属性,通过字符串操作。 #示例:反射属性 class Student: def __init__(self, name, sex, age): self.name = name self.age = age self.sex = sex def study(self): print('student is studying') deng = Student('deng', 'male', 25) #当我们获取一个对象,但是不清楚对象内部细节,就需要用反射。 def test(obj): if hasattr(obj, 'name'): print(getattr(obj, 'name', "no 'name' attribute")) test(deng) #示例:反射方法 #通过反射方法的方式为对象增加一个方法,但是注意,这样增加的方法就是一个普通函数,不会自动传值。 res = getattr(deng, 'study', None) print(res) res() def run(obj): print('student is running') setattr(deng,'run',None) res1 = getattr(deng, 'run',None) run(deng) #deng #<bound method Student.study of <__main__.Student object at 0x00000272D8DB8C50>> #student is studying #student is running
3._ _str _ _内置方法
当我们需要自定义显示内容时,就需要实现 _ _str _ _方法
#该方法必须返回一个字符串,返回是什么,打印出来就是什么。 class Test: def __init__(self,name): self.name = name def __str__(self): print('str run...') return self.name t = Test('ming') print(t)
其实,在我们将一个对象转换为字符串时,本质就是在调用这个对象的_ str _ _方法。
4. _ _del _ _内置方法
该方法在对象(程序,文件,等等)被从内存中删除时会自动执行该方法。
class Student: def __del__(self): print('对象被删除。。。') stu = Student() #创建stu对象 #当该stu对象创建完成后该程序就运行结束,就会运行del方法。 #触发__del__有两种: 1.程序自动运行结束 2.手动删除,会立即执行__del__ #示例: class Student: def __del__(self): print('对象被删除。。。') stu = Student() del stu #在这就会打印,但这是程序并未结束 import time time.sleep(5) 什么时候使用它 在python中 有自动内存管理机制 所以 python自己创建的数据 不需要我们做任何操作 但是有一种情况 我们使用python打开了一个不属于python管理的数据 比如打开了一个文件 这个文件一定是操作系统在打开 会占用系统内存 而python解释器无法操作系统内存的 所以 当你的python解释器运行结束后 文件依然处于打开状态 这时候就需要使用__del__来关闭系统资源 简单地说 当程序运行结束时 需要做一些清理操作 就使用__del__ __del__也称之为 析构函数 分析构造 并拆除这个对象
5.exec方法
该方法是解析执行python代码(字符串类型) 并且将得到的名称 存储到制定的名称空间 解释器内部也是调用它来执行代码。解释器内部也是将代码看做字符串。
该方法有三个参数:
参数一 需要一个字符串对象, 表示需要被执行的python语句
参数二 是一个字典,表示全局名称空间
参数三 是一个字典,表示局部名称空间
#示例: globals_dic = {} locals_dic = {} exec(''' a = 1 if a >1: print('ming') else: print('deng')''', globals_dic, locals_dic)
#注意:
1.如果同时制定了全局和局部的,则会将字符串中包含的名称解析后存到局部名称空间。
2.如果只传了一个传参数 则 将字符串中包含名称 解析后存到全局中。
6.元类
-
使用class可以发现,类其实是type类型的实例(对象)。
-
一切皆对象
-
元类是指 用于产生类的类 type就是元类
class Student: def study(self): print('studying') print(type(Student))
总结:
1.类由type实例化产生
2.我们可以使用type产生一个类
3.一个类由类名,类的父类,类的名称空间组成。
type类实例化可以得到类,类实例化可以得到对象。
7._ _ call _ _ 内置方法
_ _ call _ _调用的意思,在对象被调用的时候执行该方法(执行该对象所属的类)
#示例: class Person: def __call__(self, *args, **kwargs): print('call running') p = Person() #创建对象不会执行call内置方法 p() # call running 对象被调用时会自动执行该方法。
自定义元类 的目的
1.可以通过call 来控制对象的创建过程
2.可用控制类的创建过程
自定义一个元类(元类也是一个类),但该类需继承元类type。
#1.通过__call__来控制对象的创建过程 #1.创建一个元类(需要继承type) #2.覆盖__call__方法,会将正在实例化对象的类转化为传入的参数 #3.在新的__call__方法中,需要按下面编写,然后再加你需要的控制逻辑即可。 class MyMeta(type): #self表示创建对象的那个类,*args, **kwargs参数 def __call__(self, *args, **kwargs): print('MyMeta中的call') #下面三步是固定的 #1.创建对象 obj = object.__new__(self) #2.调用初始化方法 self.__init__(obj,*args,**kwargs) #3.得到一个完整的对象 return obj #先修改Person的元类为MyMeta class Person(metaclass=MyMeta): def __init__(self,name ,age): self.name = name self.age = age def __call__(self, *args, **kwargs): print('call is running...') deng = Person('deng', 26) print(deng) deng() #### MyMeta中的call <__main__.Person object at 0x00000251588D89B0> call is running... #2.通过元类控制类的创建过程: #1.创建一个元类(需要继承type) #2.覆盖__init__方法,该方法会新建类的对象,类名,父类名,名称空间,可以利用这些信息做处理 #3.对于需要控制的类,需要指定metaclass为上面元类 class MyMeta(type): def __init__(self, class_name, bases, namespace): print('=======') #控制类名必须大写 if not class_name.istitle(): print('类名必须大写开头。。。') #该代码主动抛出异常 raise TypeError('类名,开头必须大写开头。。。') if not self.__doc__: raise TypeError pass class Student(metaclass=MyMeta): ''' 这是文档注释,可以通过__doc__获取 ''' #在类的__init__中可以控制该类对象的创建过程 def __init__(self, name): print('+++++++++++++') print(self.__doc__) self.name = name print(Student.__doc__)
8.单例模式
单例 一种设计模式
单个对象,一个类如果只有一个实例,那么该类称之为单例
为什么需要单例?
class MyMeta(type): obj = None def __call__(self, *args, **kwargs): if not MyMeta.obj: obj = object.__new__(self) self.__init__(obj, *args, **kwargs) MyMeta.obj = obj return MyMeta.obj class Printer(metaclass=MyMeta): ''' 这是一个单例类,请不要直接实例化,使用get方法获取实例 ''' obj = None def __init__(self, name, type): self.name = name self.type = type def printing(self, text): print('正在打印%s' % text) @classmethod def get_printer(cls): if not cls.obj: obj = cls('ec001', 'sharp') cls.obj = obj print('创建新对象') return cls.obj p = Printer.get_printer() print(p.name) print(p) p1 = Printer('ming','002') print(p1.name) print(p1)
总结: