1,类也是对象

  1. '''
  2. 动态语言
  3. 可以在运行期间 动态生成类 修改对象属性
  4. 静态语言
  5. '''''
  6.  
  7. '''
  8. type(object_or_name, bases, dict)
  9. type(object) -> the object's type
  10. type(name, bases, dict) -> a new type
  11. '''
  12. obj = type("TestClass",(object,),{})
  13. print(obj) #<class '__main__.TestClass'>
  14.  
  15. class B(object): #type("B",(object,),{"name":"rose"})
  16. name = "rose"
  17.  
  18. #模拟解释器创建类的过程
  19. def test1(a):
  20. print(a)
  21.  
  22. def test2(self,b):
  23. print(self,b)
  24.  
  25. class_name = "C"
  26. bases = (object,)
  27. name_dic = {"name":"jack","test1":test1,"test2":test2}
  28.  
  29. C = type(class_name,bases,name_dic)
  30. # print(C) #<class '__main__.C'>
  31. c1 = C()
  32. print(c1) #<__main__.C object at 0x000001EFEC877550>
  33. c1.test2(100) #<__main__.C object at 0x0000021F31807550> 100

2 , exec

  1. glob = {}
  2. locl = {}
  3.  
  4. code = """
  5. def test(a):
  6. print(a)
  7. """
  8.  
  9. exec(code,glob,locl)
  10.  
  11. # print(glob) #打印系统内置函数
  12. print(locl) #{'test': <function test at 0x000001376F36C2F0>}
  13. locl["test"](100)
  14.  
  15. #exec 可以执行字符串形式的python代码,并且会把执行过程中产生的名字,放到局部名称空间中
  16. class_test = """
  17. class A:
  18. def test(self):
  19. print(self)
  20. """
  21. loca2 = {}
  22. exec(class_test,None,loca2)
  23. print(loca2) #{'A': <class '__main__.A'>}
  24.  
  25. # eval(class_test) #报错,eval用于处理单行字符串的表达式

3,元类

  1. class person():
  2.  
  3. def __init__(self,name):
  4. self.name = name
  5.  
  6. def SAYHI(self):
  7. print(self.name)
  8.  
  9. '''
  10. 类名必须大写开头,方法名必须全部小写
  11. 应用场景:用于限制类,满足某些条件,例如上述要求
  12. type类已经具备了创建类的能力,但是现在不能满足我们的要求
  13. 需要对已有的功能进行扩展或修改
  14. 方式:
  15. 1,直接修改源代码 ,行不通
  16. 2,自定义新的元类
  17. '''
  18. class MyMetaClass(type):
  19. pass
  20.  
  21. #默认创建类时,是找的type来实例化的
  22. class Person(metaclass=MyMetaClass):
  23. pass
  24.  
  25. class Student:
  26. def __init__(self):
  27. pass
  28.  
  29. print(type(Person)) #<class '__main__.MyMetaClass'>
  30. print(type(Student)) #<class 'type'>
  31.  
  32. s = Student() #实例化对象时, 1,产生空对象,2,自动执行__init__
  33.  
  34. #创建类对象时也是一样的,会先创建空的类对象,在调用__init__()方法
  35. # Person = MyMetaClass()
  1. class MyMetaClass(type):
  2. def __init__(self,class_name,bases,name_dic):
  3. #元类中的self表示的都是类对象
  4. print(self) #<class '__main__.Student'>
  5.  
  6. #不要忘记调用父类的初始化
  7. super().__init__(class_name,bases,name_dic)
  8. print(name_dic)
  9.  
  10. #类名必须首字母大写,否则直接抛出异常
  11. if not class_name.istitle():
  12. print('类名必须大写!')
  13. raise Exception
  14.  
  15. #控制类中方法名必须全部小写
  16. for k in name_dic:
  17. if str(type(name_dic[k])) == "<class 'function'>":
  18. if not k.islower():
  19. raise Exception('方法名必须全小写!')
  20.  
  21. #会自动调用其元类中的__init__方法传入,类对象本身,类名称,父类们,名称空间
  22. class Student(object,metaclass=MyMetaClass): #MyMetaClass("Student",(object,),{})
  23. NAME = 10
  24. def asdfA(self):
  25. print('SNY')

3 , 元类中 __new__

  1. class MeMetaClass(type):
  2.  
  3. def __init__(self,class_name,bases,name_dic):
  4. # super().__init__(class_name,bases,name_dic)
  5. print("init")
  6.  
  7. #该方法会在实例化类对象时自动调用并且在__init__之前调用
  8. #其作用是用于创建新的类对象的
  9. #注意这里必须调用type类中的__new__否则将无法产生类对象,并且返回其结果
  10. def __new__(cls, *args, **kwargs):
  11. #cls 表示元类自己即MyMetaClass
  12. print("new")
  13. print(args,kwargs) #('Person', (), {'__module__': '__main__', '__qualname__': 'Person'}) {}
  14. return type.__new__(cls,*args,**kwargs) #如果覆盖__new__一定要写上这行代码
  15.  
  16. class Person(metaclass=MeMetaClass):
  17. pass
  18.  
  19. print(Person) #<class '__main__.Person'>
  20.  
  21. #就算__init__中什么都不写,这个类对象其实已经创建完成了,该有的属性都有了
  22. #这是与普通类不同之处
  23.  
  24. print(Person.__name__) #不会报错
  25.  
  26. class Student:
  27. def __init__(self,name):
  28. pass
  29.  
  30. s = Student('张三')
  31. # s.name #报错
  1. #练习1:
  2.  
  3. #需求:要求每个类必须包含__doc__属性,__doc__用于访问一个对象的注释信息
  4. class A:
  5. '''
  6. this is A
  7. '''
  8. pass
  9.  
  10. print(A.__doc__)
  11.  
  12. #如果你要控制类的创建,那就自定义元类 覆盖__init__
  13. class DocMetaClass(type):
  14. def __init__(self,class_name,bases,name_dic):
  15. super().__init__(class_name,bases,name_dic)
  16.  
  17. # if not("__doc__" in name_dic and name_dic["__doc__"]):
  18. # raise Exception
  19.  
  20. #如果doc为空,则抛异常
  21. if not self.__doc__:
  22. raise Exception
  23.  
  24. class Person(metaclass=DocMetaClass):
  25. pass
  26.  
  27. print(type(object))

4 , 元类中 __call__

  1. class Person:
  2. #调用对象时,会执行对象所在类中的__call__方法
  3. def __call__(self, *args, **kwargs):
  4. print("call")
  5. print(args)
  6. print(kwargs)
  7.  
  8. p = Person()
  9. p()
  10.  
  11. '''
  12. 练习:将类中的为字符串的属性名转为大写
  13. '''
  14. class MyMeta(type):
  15. #获得某个类的实例
  16. def __call__(self, *args, **kwargs):
  17. print("call")
  18. # return super().__call__(*args,**kwargs)
  19. print(args) #('jack', 'women', 18)
  20. print(kwargs) #{}
  21.  
  22. new_args = []
  23. for i in args:
  24. if isinstance(i,str):
  25. new_args.append(i.upper())
  26. else:
  27. new_args.append(i)
  28. print(new_args) #['JACK', 'WOMEN', 18]
  29. return super().__call__(*new_args,**kwargs)
  30.  
  31. #注意:__new__ __init__是创建类对象时还会执行
  32. #__call__ 类对象要产生实例时执行
  33.  
  34. class Student(metaclass=MyMeta):
  35. def __init__(self,name,gender,age):
  36. self.name = name
  37. self.gender = gender
  38. self.age = age
  39.  
  40. s = Student('jack','women',18)
  41. print(s.age) #
  42. print(s.gender) #WOMEN
  43.  
  44. class Person(metaclass=MyMeta):
  45. def __init__(self,name,gender):
  46. self.name = name
  47. self.gender = gender
  48.  
  49. p = Person('rose','name')
  50. print(p.name) #ROSE

5, 单例模式

  1. '''
  2. 单例模式
  3. 是一种设计模式,是单个实例的意思
  4. 当你需要 让你的类仅有一个实例时,那就可以使用单例模式
  5. '''''
  6. class Person:
  7. obj = None
  8. def __init__(self,name,age,gender):
  9. self.name = name
  10. self.age = age
  11. self.gender = gender
  12.  
  13. def say(self):
  14. print('my name is %s my 姑姑 is 龙妈'%self.name)
  15.  
  16. @classmethod
  17. def get_instance(cls):
  18. if not cls.obj:
  19. obj = cls('小龙女',19,'women')
  20. cls.obj = obj
  21. print('创建新的了')
  22. return cls.obj
  23.  
  24. # 调用了多次,产生了多个实例 (地址不一样)
  25. p1 = Person('姬如雪','','women')
  26. p1.say()
  27. p2 = Person('姬如雪','','women')
  28. p2.say()
  29. print(p1,p2) #<__main__.Person object at 0x000001A5A87076A0> <__main__.Person object at 0x000001A5A8707710>
  30.  
  31. #限制了类的实例化,如果为同一个类则只实例化一次 (地址一样)
  32. p1 = Person.get_instance()
  33. p1.say()
  34. p2 = Person.get_instance()
  35. p2.say()
  36.  
  37. print(p1) #<__main__.Person object at 0x000002396C2F75C0>
  38. print(p2) #<__main__.Person object at 0x000002396C2F75C0>

6 , 元类实现单例

  1. class SingMeta(type):
  2. # 创建类时会执行__init__,在这为每一类设置一个obj属性 默认为None
  3. def __init__(self, a, b, c):
  4. super().__init__(a, b, c)
  5. self.obj = None
  6. print(self.obj)
  7.  
  8. # 当类要创建对象时会执行该方法
  9. def __call__(self, *args, **kwargs):
  10. # 判断这个类如果已经有了实例了就直接返回,从而实现单例
  11. if self.obj:
  12. return self.obj
  13.  
  14. # 如果没有,则创建新的实例保存到类中
  15. obj = type.__call__(self, *args, **kwargs)
  16. self.obj = obj
  17. return obj
  18.  
  19. class Person(metaclass=SingMeta):
  20. def __init__(self, name, age, gender):
  21. self.name = name
  22. self.age = age
  23. self.gender = gender
  24.  
  25. def say(self):
  26. print("my name is %s my 姑姑 is 龙妈" % self.name)
  27.  
  28. class Student(metaclass=SingMeta):
  29. def __init__(self, name, age, gender):
  30. self.name = name
  31. self.age = age
  32. self.gender=gender
  33.  
  34. def say(self):
  35. print("my name is %s my 姑姑 is 龙妈" % self.name)
  36.  
  37. p1 = Person('姬如雪',20,'women')
  38. p2 = Person('姬如雪',20,'women')
  39. print(p1) #<__main__.Person object at 0x000001F512867668>
  40. print(p2) #<__main__.Person object at 0x000001F512867668>
  41.  
  42. stu1 = Student('史蒂夫',18,'man')
  43. stu2 = Student('史蒂夫',18,'man')
  44. print(stu1) #<__main__.Student object at 0x0000013B18EB7780>
  45. print(stu2) #<__main__.Student object at 0x0000013B18EB7780>

7, 单例案例:

  1. class Single(type):
  2. def __init__(self,a,b,c):
  3. super().__init__(a,b,c)
  4. self.obj = None
  5.  
  6. def __call__(self, *args, **kwargs):
  7. if self.obj:
  8. return self.obj
  9.  
  10. obj = type.__call__(self,*args,**kwargs)
  11. self.obj = obj
  12. return obj
  13.  
  14. class QQPlayer(metaclass=Single):
  15. def __init__(self,voice_value,repeat=False):
  16. self.voice_value =voice_value
  17. self.repeat = repeat
  18.  
  19. def play(self,file_path):
  20. if hasattr(self,'file_path'):
  21. self.stop()
  22.  
  23. print('正在播放%s'%file_path)
  24. self.file_path = file_path
  25.  
  26. def stop(self):
  27. print('%s--停止播放'%self.file_path)
  28.  
  29. #问题:每次播放一次,都是实例化一次
  30. ply = QQPlayer(100,True)
  31. ply.play('如果.mp3')
  32.  
  33. ply1 = QQPlayer(100,True)
  34. ply1.play('后来.mp3')
  35.  
  36. ply2 = QQPlayer(100,True)
  37. ply2.play('田鸥.mp3')
  38.  
  39. print(ply) #<__main__.QQPlayer object at 0x000002B349C87550>
  40. print(ply1) #<__main__.QQPlayer object at 0x000002B349C87550>
  41. print(ply2) #<__main__.QQPlayer object at 0x000002B349C87550>

8, 常见异常

  1. '''
  2. 语法错误: SyntaxError: invalid syntax
  3. '''''
  4. # if num > 1
  5.  
  6. # print('hello')
  7. # a =
  8. # b = 10
  9.  
  10. '''
  11. 类型错误: TypeError: 'int' object is not subscriptable
  12. '''
  13. # 1[:]
  14.  
  15. '''
  16. 下标错误: IndexError: list index out of range
  17. '''
  18. # li = [1,2,3,4]
  19. # print(li[10])
  20.  
  21. '''
  22. KeyError: 'xxx'
  23. '''
  24. # {'name':1}['xxx']
  25.  
  26. '''
  27. FileNotFoundError: [Errno 2] No such file or directory: 'xxx'
  28. '''
  29. # with open('xxx')as f:
  30. # pass
  31.  
  32. '''
  33. NameError: name 'name' is not defined
  34. '''
  35. # def func():
  36. # name
  37. # pass
  38. # func()
  39.  
  40. '''
  41. 1,捕捉异常
  42. '''
  43. #语法一:
  44. try:
  45. print('start')
  46. {'name':1}['xxx']
  47. print('over')
  48. except:
  49. print(' key 不存在')
  50.  
  51. #语法二: 在except 中指定要处理的异常类型
  52. try:
  53. print('start')
  54. {'name':1}['xxx']
  55. 1[:]
  56. print('over')
  57. except KeyError:
  58. print('出问题了')
  59.  
  60. #语法三 : 在except中可以指定多种异常类型,使用统一的处理方案,没啥用
  61. try:
  62. print('start')
  63. {'name':1}['xxx']
  64. 1[:]
  65. print('over')
  66. except(KeyError,TypeError):
  67. print('出问题了')
  68.  
  69. #语法四 : 一个try可以跟多个except语句 每个处理不同的异常
  70. try:
  71. print('start')
  72. {'name': 1}['xxx']
  73. 1[:]
  74. print('over')
  75. except KeyError:
  76. print('Key 不存在!')
  77. except TypeError:
  78. print('要操作的类型不对啊!')
  79.  
  80. # 语法5 万能异常 尽量少用 因为 无法知道具体原因
  81. try:
  82. print("start")
  83. # {"name":1}["xxx"]
  84. # 1[:]
  85. # name
  86. print("over")
  87. except Exception:
  88. print("不知道啥原因 反正有问题!")
  89.  
  90. # 语法6 给异常对象取别名 从而访问一异常对象
  91. # 之所以 能处理任何类型 是因为 Exception 是所有异常类的父类
  92. try:
  93. print("start")
  94. # {"name":1}["xxx"]
  95. 1[:]
  96. # name
  97. print("over")
  98. except Exception as e:
  99. print("有问题! 原因为%s" % e)
  100. print(type(e))
  101.  
  102. # 最常用的方式 在处理异常时 一定要记得打印一下异常信息 否则 你的程序不会出问题 但是也不会正常运行
  103. try:
  104. name
  105. except NameError as e:
  106. print(e)
  107.  
  108. # 观光语法 else 将在代码没有异常时执行
  109. try:
  110. a = 10
  111. except Exception as e:
  112. print(e)
  113. else:
  114. print("else???????? ")
  115.  
  116. class FileTypeException(Exception):
  117. pass
  118.  
  119. class Player:
  120. def play(self,path):
  121. if not path.endswith("mp3"):
  122. # print("文件类错误!")
  123. # z主动抛出异常
  124. raise FileTypeException("仅能播放mp3格式.....")
  125. print("播放%s" % path)
  126.  
  127. assert path.endswith("mp3")
  128. print("播放%s" % path)
  129.  
  130. p = Player()
  131. p.play("xxx.mp4")

exec , 元类,__new__, __call__ , 单例模式 , 异常的更多相关文章

  1. 【原创】Python 对象创建过程中元类, __new__, __call__, __init__ 的处理

    原始type: type是最原始的元类,其__call__方法是在你使用" t_class = type(classname_string, base_classes_tuple, attr ...

  2. 29 内置方法 eval | exec 元类 单例

    eval与exec内置方法 将字符串作为执行目标,得到响应结果 eval常用作类型转换:该函数执行完有返回值 exec拥有执行更复杂的字符串:可以形成名称空间 eval内置函数的使用场景:   1.执 ...

  3. python 之 面向对象(元类、__call__、单例模式)

    7.13 元类 元类:类的类就是元类,我们用class定义的类来产生我们自己的对象的,内置元类type是用来专门产生class定义的类 code=""" global x ...

  4. 面向对象高级C(元类补充及单例模式)

    元类有关知识点补充 #类的名称空间 类的名称空间不能用类似字典的方法修改,例如School类里面有name属性xxx,那么我用School.__dict__['name'] = 'yyy'就会报错&q ...

  5. [Python之路] 元类(引申 单例模式)

    一.类也是对象 当我们定义一个变量或者函数的时候,我们可以在globals()的返回值字典中找到响应的映射: def A(): print("This is function A" ...

  6. 通过 python的 __call__ 函数与元类 实现单例模式

    简单一句话,当一个类实现__call__方法时,这个类的实例就会变成可调用对象. 直接上测试代码 class ClassA: def __call__(self, *args, **kwargs): ...

  7. 类和对象的创建过程(元类,__new__,__init__,__call__)

    一. type() 1.创建类的两种方式 方式一 class MyClass(object): def func(self,name): print(name) myc = MyClass() pri ...

  8. python 入门基础24 元类、单例模式

    内容目录: 一.元类 二.单例模式 一.元类 1 什么是元类: 源自一句话:在python中,一切皆对象,而对象都是由类实例化得到的 class OldboyTeacher: def __init__ ...

  9. day37-2元类,单例模式

    目录 元类 造类的第一种形式 class做了什么事 控制元类产生的类 控制元类产生的对象 实例化类 加上元类后类的属性查找顺序 元类控制模版 单例模式 1. 使用类方法的特性 2. 使用装饰器 3. ...

随机推荐

  1. Flume NG部署

    本次配置单节点的Flume NG 1.下载flume安装包 下载地址:(http://flume.apache.org/download.html) apache-flume-1.6.0-bin.ta ...

  2. Storm概念学习系列之事务

    不多说,直接上干货! 事务 这里的事务是专门针对Topology提出来的,是为了解决元组在处理失败重新发送后的一系列问题的.简而言之,事务拓扑(transactional topology)就是指St ...

  3. java使用线程请求访问每次间隔10分钟连续5次,之后停止请求

    java使用线程请求访问每次间隔10分钟连续5次,收到相应的时候停止请求 package com.qlwb.business.util; /** * * * @类编号: * @类名称:RequestT ...

  4. chrome浏览器表单自动填充默认样式-autofill

    Chrome会在客户登陆过某网站之后, 会自动记住密码 当你下次再次进入该网站的时候, 可以自由的选择登陆的账号, Chrome会为你自动填充密码. 而你无需再输入密码 这本身是一个很好的功能, 但是 ...

  5. java(itext) 一个很简单的PDF表格生成工具

    先上个效果图 因为做的项目涉及到数据预测,其中有大量打印业务来支撑实体店的运营,因为注重的是数据,要求简洁,清晰,所以写了个很简单也很实用的工具类. 如果需要编写样式或者插入背景,都可以查阅itex官 ...

  6. 如何从MYSQL官方YUM仓库安装MYSQL5.x 原理一样只要获取对的仓库依赖安装对的仓库依赖就ok了,我就是用这种安装的5.7

    如何从MYSQL官方YUM仓库安装MYSQL5.6 2013年10月,MySQL开发团队正式宣布支持Yum仓库,这就意味着我们现在可以从这个Yum库中获得最新和最优版的MySQL安装包.本文将在一台全 ...

  7. $.ajax防止多次点击重复提交的方法

    第一种:使用$.ajaxPrefilter( [dataTypes], handler(options, originalOptions, jqXHR) ) 方法:$.ajaxPrefilter()方 ...

  8. js为页面元素添加水印

    近期有需求为页面部分区域添加上水印,通过在网上找到了js为页面添加水印的方法,后来经过自己的改进,可以实现为页面部分元素添加水印,最终效果如下图: 代码如下: function watermark(s ...

  9. 未整理js

    函数+对象=方法 方法是动作 有参数的函数=实例 使用new关键字和函数来创建一个实例 var p =new Point(1,1)//平面几何的点 表示遍历的语句样子: for(var i =0; i ...

  10. 【转/TCP协议编程】 基于TCP的Socket 编程

    基于TCP(面向连接)的socket编程,分为客户端和服务器端. 客户端的流程如下: (1)创建套接字(socket) (2)向服务器发出连接请求(connect) (3)和服务器端进行通信(send ...