1,类也是对象

'''
动态语言可以在运行期间 动态生成类 修改对象属性
静态语言
''''''''
type(object_or_name, bases, dict)
type(object) -> the object's type
type(name, bases, dict) -> a new type
'''
obj = type("TestClass",(object,),{})
print(obj)          #<class '__main__.TestClass'>class B(object):    #type("B",(object,),{"name":"rose"})name = "rose"#模拟解释器创建类的过程
def test1(a):print(a)def test2(self,b):print(self,b)class_name = "C"
bases = (object,)
name_dic = {"name":"jack","test1":test1,"test2":test2}C = type(class_name,bases,name_dic)
# print(C)    #<class '__main__.C'>
c1 = C()
print(c1)      #<__main__.C object at 0x000001EFEC877550>
c1.test2(100)   #<__main__.C object at 0x0000021F31807550> 100

2 , exec

glob = {}
locl = {}code = """
def test(a):print(a)
"""exec(code,glob,locl)# print(glob)   #打印系统内置函数
print(locl)     #{'test': <function test at 0x000001376F36C2F0>}
locl["test"](100)#exec 可以执行字符串形式的python代码,并且会把执行过程中产生的名字,放到局部名称空间中
class_test = """
class A:def test(self):print(self)
"""
loca2 = {}
exec(class_test,None,loca2)
print(loca2)        #{'A': <class '__main__.A'>}# eval(class_test)  #报错,eval用于处理单行字符串的表达式

3,元类

class person():def __init__(self,name):self.name = namedef SAYHI(self):print(self.name)'''
类名必须大写开头,方法名必须全部小写
应用场景:用于限制类,满足某些条件,例如上述要求
type类已经具备了创建类的能力,但是现在不能满足我们的要求
需要对已有的功能进行扩展或修改
方式:1,直接修改源代码 ,行不通2,自定义新的元类
'''
class MyMetaClass(type):pass#默认创建类时,是找的type来实例化的
class Person(metaclass=MyMetaClass):passclass Student:def __init__(self):passprint(type(Person))     #<class '__main__.MyMetaClass'>
print(type(Student))    #<class 'type'>

s = Student()           #实例化对象时, 1,产生空对象,2,自动执行__init__#创建类对象时也是一样的,会先创建空的类对象,在调用__init__()方法
# Person = MyMetaClass()

class MyMetaClass(type):def __init__(self,class_name,bases,name_dic):#元类中的self表示的都是类对象print(self)     #<class '__main__.Student'>#不要忘记调用父类的初始化super().__init__(class_name,bases,name_dic)print(name_dic)#类名必须首字母大写,否则直接抛出异常if not class_name.istitle():print('类名必须大写!')raise Exception#控制类中方法名必须全部小写for k in name_dic:if str(type(name_dic[k])) == "<class 'function'>":if not k.islower():raise Exception('方法名必须全小写!')#会自动调用其元类中的__init__方法传入,类对象本身,类名称,父类们,名称空间
class Student(object,metaclass=MyMetaClass):    #MyMetaClass("Student",(object,),{})NAME = 10def asdfA(self):print('SNY')

3 , 元类中 __new__

class MeMetaClass(type):def __init__(self,class_name,bases,name_dic):# super().__init__(class_name,bases,name_dic)print("init")#该方法会在实例化类对象时自动调用并且在__init__之前调用#其作用是用于创建新的类对象的#注意这里必须调用type类中的__new__否则将无法产生类对象,并且返回其结果def __new__(cls, *args, **kwargs):#cls 表示元类自己即MyMetaClassprint("new")print(args,kwargs)      #('Person', (), {'__module__': '__main__', '__qualname__': 'Person'}) {}return type.__new__(cls,*args,**kwargs)   #如果覆盖__new__一定要写上这行代码class Person(metaclass=MeMetaClass):passprint(Person)   #<class '__main__.Person'>#就算__init__中什么都不写,这个类对象其实已经创建完成了,该有的属性都有了
#这是与普通类不同之处print(Person.__name__)  #不会报错class Student:def __init__(self,name):passs = Student('张三')
# s.name      #报错

#练习1:

#需求:要求每个类必须包含__doc__属性,__doc__用于访问一个对象的注释信息
class A:'''this is A'''passprint(A.__doc__)#如果你要控制类的创建,那就自定义元类 覆盖__init__
class DocMetaClass(type):def __init__(self,class_name,bases,name_dic):super().__init__(class_name,bases,name_dic)# if not("__doc__" in name_dic and name_dic["__doc__"]):#     raise Exception#如果doc为空,则抛异常if not self.__doc__:raise Exceptionclass Person(metaclass=DocMetaClass):passprint(type(object))

4 , 元类中 __call__

class Person:#调用对象时,会执行对象所在类中的__call__方法def __call__(self, *args, **kwargs):print("call")print(args)print(kwargs)p = Person()
p()'''
练习:将类中的为字符串的属性名转为大写
'''
class MyMeta(type):#获得某个类的实例def __call__(self, *args, **kwargs):print("call")# return super().__call__(*args,**kwargs)print(args)     #('jack', 'women', 18)print(kwargs)   #{}
new_args = []for i in args:if isinstance(i,str):new_args.append(i.upper())else:new_args.append(i)print(new_args)     #['JACK', 'WOMEN', 18]return super().__call__(*new_args,**kwargs)#注意:__new__  __init__是创建类对象时还会执行
#__call__ 类对象要产生实例时执行class Student(metaclass=MyMeta):def __init__(self,name,gender,age):self.name = nameself.gender = genderself.age = ages = Student('jack','women',18)
print(s.age)        #18
print(s.gender)     #WOMENclass Person(metaclass=MyMeta):def __init__(self,name,gender):self.name = nameself.gender = genderp = Person('rose','name')
print(p.name)   #ROSE

5, 单例模式

'''
单例模式是一种设计模式,是单个实例的意思当你需要 让你的类仅有一个实例时,那就可以使用单例模式
'''''
class Person:obj = Nonedef __init__(self,name,age,gender):self.name = nameself.age = ageself.gender = genderdef say(self):print('my name is %s my 姑姑 is 龙妈'%self.name)@classmethoddef get_instance(cls):if not cls.obj:obj = cls('小龙女',19,'women')cls.obj = objprint('创建新的了')return cls.obj# 调用了多次,产生了多个实例  (地址不一样)
p1 = Person('姬如雪','20','women')
p1.say()
p2 = Person('姬如雪','20','women')
p2.say()
print(p1,p2)  #<__main__.Person object at 0x000001A5A87076A0> <__main__.Person object at 0x000001A5A8707710>#限制了类的实例化,如果为同一个类则只实例化一次 (地址一样)
p1 = Person.get_instance()
p1.say()
p2 = Person.get_instance()
p2.say()print(p1)   #<__main__.Person object at 0x000002396C2F75C0>
print(p2)   #<__main__.Person object at 0x000002396C2F75C0>

6 , 元类实现单例

class SingMeta(type):# 创建类时会执行__init__,在这为每一类设置一个obj属性 默认为Nonedef __init__(self, a, b, c):super().__init__(a, b, c)self.obj = Noneprint(self.obj)# 当类要创建对象时会执行该方法def __call__(self, *args, **kwargs):# 判断这个类如果已经有了实例了就直接返回,从而实现单例if self.obj:return self.obj# 如果没有,则创建新的实例保存到类中obj = type.__call__(self, *args, **kwargs)self.obj = objreturn objclass Person(metaclass=SingMeta):def __init__(self, name, age, gender):self.name = nameself.age = ageself.gender = genderdef say(self):print("my name is %s  my 姑姑 is 龙妈" % self.name)class Student(metaclass=SingMeta):def __init__(self, name, age, gender):self.name = nameself.age = ageself.gender=genderdef say(self):print("my name is %s  my 姑姑 is 龙妈" % self.name)p1 = Person('姬如雪',20,'women')
p2 = Person('姬如雪',20,'women')
print(p1)       #<__main__.Person object at 0x000001F512867668>
print(p2)       #<__main__.Person object at 0x000001F512867668>

stu1 = Student('史蒂夫',18,'man')
stu2 = Student('史蒂夫',18,'man')
print(stu1)     #<__main__.Student object at 0x0000013B18EB7780>
print(stu2)     #<__main__.Student object at 0x0000013B18EB7780>

7, 单例案例:

class Single(type):def __init__(self,a,b,c):super().__init__(a,b,c)self.obj = Nonedef __call__(self, *args, **kwargs):if self.obj:return self.objobj = type.__call__(self,*args,**kwargs)self.obj = objreturn objclass QQPlayer(metaclass=Single):def __init__(self,voice_value,repeat=False):self.voice_value =voice_valueself.repeat = repeatdef play(self,file_path):if hasattr(self,'file_path'):self.stop()print('正在播放%s'%file_path)self.file_path = file_pathdef stop(self):print('%s--停止播放'%self.file_path)#问题:每次播放一次,都是实例化一次
ply = QQPlayer(100,True)
ply.play('如果.mp3')ply1 = QQPlayer(100,True)
ply1.play('后来.mp3')ply2 = QQPlayer(100,True)
ply2.play('田鸥.mp3')print(ply)      #<__main__.QQPlayer object at 0x000002B349C87550>
print(ply1)     #<__main__.QQPlayer object at 0x000002B349C87550>
print(ply2)     #<__main__.QQPlayer object at 0x000002B349C87550>

8, 常见异常

'''
语法错误: SyntaxError: invalid syntax
'''''
# if num > 1# print('hello')
# a =
# b = 10'''
类型错误: TypeError: 'int' object is not subscriptable
'''
# 1[:]'''
下标错误: IndexError: list index out of range
'''
# li = [1,2,3,4]
# print(li[10])'''
KeyError: 'xxx'
'''
# {'name':1}['xxx']'''
FileNotFoundError: [Errno 2] No such file or directory: 'xxx'
'''
# with open('xxx')as f:
#     pass'''
NameError: name 'name' is not defined
'''
# def func():
#     name
#     pass
# func()'''
1,捕捉异常
'''
#语法一:
try:print('start'){'name':1}['xxx']print('over')
except:print(' key 不存在')#语法二: 在except 中指定要处理的异常类型
try:print('start'){'name':1}['xxx']1[:]print('over')
except KeyError:print('出问题了')#语法三 : 在except中可以指定多种异常类型,使用统一的处理方案,没啥用
try:print('start'){'name':1}['xxx']1[:]print('over')
except(KeyError,TypeError):print('出问题了')#语法四 : 一个try可以跟多个except语句 每个处理不同的异常
try:print('start'){'name': 1}['xxx']1[:]print('over')
except KeyError:print('Key 不存在!')
except TypeError:print('要操作的类型不对啊!')# 语法5 万能异常   尽量少用 因为 无法知道具体原因
try:print("start")# {"name":1}["xxx"]# 1[:]# nameprint("over")
except Exception:print("不知道啥原因 反正有问题!")# 语法6 给异常对象取别名 从而访问一异常对象
# 之所以 能处理任何类型 是因为  Exception 是所有异常类的父类
try:print("start")# {"name":1}["xxx"]1[:]# nameprint("over")
except Exception as e:print("有问题! 原因为%s" % e)print(type(e))# 最常用的方式 在处理异常时 一定要记得打印一下异常信息   否则 你的程序不会出问题  但是也不会正常运行
try:name
except NameError as e:print(e)# 观光语法  else 将在代码没有异常时执行
try:a = 10
except Exception as e:print(e)
else:print("else???????? ")class FileTypeException(Exception):passclass Player:def play(self,path):if not path.endswith("mp3"):# print("文件类错误!")# z主动抛出异常raise FileTypeException("仅能播放mp3格式.....")print("播放%s" % path)assert path.endswith("mp3")print("播放%s" % path)p = Player()
p.play("xxx.mp4")

转载于:https://www.cnblogs.com/HZLS/p/10925601.html

exec , 元类,__new__, __call__ , 单例模式 , 异常相关推荐

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

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

  2. Python中的元类及元类实现的单例模式

    https://www.cnblogs.com/tkqasn/p/6524879.html 在看一些框架源代码的过程中碰到很多元类的实例,看起来很吃力很晦涩:在看python cookbook中关于元 ...

  3. python高端写法_python高级篇:使用元类方式实现单例模式详解

    对于编程开发的朋友来说,设计模式应该最为熟悉不过了,如果要谈到哪种设计模式最为简单,也最容易理解,首当其冲的"单例模式"应该不为过了.本文主要讲解在python3中如何使用元类实现 ...

  4. python 元类 详解_Python 元类详解 __new__、__init__、__call__、__metacalss__

    了解元类之前,先了解几个魔术方法: __new__.__init__.__call__ __new__: 对象的创建,是一个静态方法,第一个参数是cls.(想想也是,不可能是self,对象还没创建,哪 ...

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

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

  6. 深刻理解Python中的元类(metaclass)以及元类实现单例模式

    在看一些框架源代码的过程中碰到很多元类的实例,看起来很吃力很晦涩:在看python cookbook中关于元类创建单例模式的那一节有些疑惑.因此花了几天时间研究下元类这个概念.通过学习元类,我对pyt ...

  7. 编写python程序、创建名为class的数据库_Python中的元类(metaclass)以及元类实现单例模式...

    一.理解类也是对象 在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇特.在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段.在P ...

  8. python元类_python中的元类 metaclass

    python中的元类 metaclass 在python中,类(class)本身也是一个实例对象, 它的类型则是元类, 如果没有指明, 则自定义类的类型是type. 换言之, 我们所定义的普通类都是t ...

  9. python元类深入理解

    1.python 中的类 在python中,类也是一个对象,只不过这个对象拥有生成实例的能力,我们一般使用class XXX来定义一个类,在python解释器执行到这个地方的时候会自动创建出这个对象, ...

最新文章

  1. 结合脑成像技术与人工智能,破除自杀的“诅咒”
  2. Solaris10之SVM简析
  3. 专访友盟CEO叶谦:深挖海量终端用户数据的价值
  4. 盘点VS2015 预览版的5个新特性
  5. 如何实现Java类隔离加载?
  6. 命令行下载利器- Aria2
  7. keepalived高可用集群学习以及实验总结
  8. SQL Server between...and...语句使用举例
  9. java小软件_JAVA小应用程序 。。。。。。。。。。。
  10. mix2线刷开发板救砖_小米小米Mix 2手机快速救砖,线刷教程分享,小白轻松救活手机...
  11. 小米笔记本pro黑苹果原厂intel蓝牙亲测可用!!
  12. 一个简易的QQ魔法卡片炼卡消耗计算器
  13. win10计算机管理找不到用户,win10重装系统后管理账户不见了,win10怎么找到管理账户?...
  14. mipi-csi-2解读_CSI:Visual Studio-无法将索引X处的Unicode字符转换为指定的代码页
  15. 笔记本不能联网,WiFi图标消失解决方法。
  16. C# C++ 互操作:C++向C#输出不定长数组或指针的实现
  17. 计算机辅助教育课件有哪些类型,多媒体计算机辅助教学 (2).ppt
  18. idea 安装vue.js插件
  19. 杨家海 清华大学 研究员,博导
  20. Git教程 | (9) 自定义Git和使用SourceTree

热门文章

  1. js批量打包下载图片
  2. UP Squared Board评测——毫无疑问,这是全球性能最强的创客板了
  3. 来到杭州,你会想起哪句诗词?
  4. 听,知天下、明事理(喜马拉雅App)
  5. 项目管理没有思路,还是得靠它
  6. Kubernetes In Action 学习笔记 Chapter3,4,5 (一)Pod,副本机制,守护进程与Job
  7. python取模运算_Python中的取模运算方法
  8. cc1101 简单入门
  9. 在制图时,对于城市,既想让其显示城市名又想用图形将名称圈起来,怎么设置?
  10. JSON与string的互相转换