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 = name def SAYHI(self):
print(self.name) '''
类名必须大写开头,方法名必须全部小写
应用场景:用于限制类,满足某些条件,例如上述要求
type类已经具备了创建类的能力,但是现在不能满足我们的要求
需要对已有的功能进行扩展或修改
方式:
1,直接修改源代码 ,行不通
2,自定义新的元类
'''
class MyMetaClass(type):
pass #默认创建类时,是找的type来实例化的
class Person(metaclass=MyMetaClass):
pass class Student:
def __init__(self):
pass print(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 = 10
def 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 表示元类自己即MyMetaClass
print("new")
print(args,kwargs) #('Person', (), {'__module__': '__main__', '__qualname__': 'Person'}) {}
return type.__new__(cls,*args,**kwargs) #如果覆盖__new__一定要写上这行代码 class Person(metaclass=MeMetaClass):
pass print(Person) #<class '__main__.Person'> #就算__init__中什么都不写,这个类对象其实已经创建完成了,该有的属性都有了
#这是与普通类不同之处 print(Person.__name__) #不会报错 class Student:
def __init__(self,name):
pass s = Student('张三')
# s.name #报错
#练习1:

#需求:要求每个类必须包含__doc__属性,__doc__用于访问一个对象的注释信息
class A:
'''
this is A
'''
pass print(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 Exception class Person(metaclass=DocMetaClass):
pass print(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 = name
self.gender = gender
self.age = age s = Student('jack','women',18)
print(s.age) #
print(s.gender) #WOMEN class Person(metaclass=MyMeta):
def __init__(self,name,gender):
self.name = name
self.gender = gender p = Person('rose','name')
print(p.name) #ROSE

5, 单例模式

'''
单例模式
是一种设计模式,是单个实例的意思
当你需要 让你的类仅有一个实例时,那就可以使用单例模式
'''''
class Person:
obj = None
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender def say(self):
print('my name is %s my 姑姑 is 龙妈'%self.name) @classmethod
def get_instance(cls):
if not cls.obj:
obj = cls('小龙女',19,'women')
cls.obj = obj
print('创建新的了')
return cls.obj # 调用了多次,产生了多个实例 (地址不一样)
p1 = Person('姬如雪','','women')
p1.say()
p2 = Person('姬如雪','','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属性 默认为None
def __init__(self, a, b, c):
super().__init__(a, b, c)
self.obj = None
print(self.obj) # 当类要创建对象时会执行该方法
def __call__(self, *args, **kwargs):
# 判断这个类如果已经有了实例了就直接返回,从而实现单例
if self.obj:
return self.obj # 如果没有,则创建新的实例保存到类中
obj = type.__call__(self, *args, **kwargs)
self.obj = obj
return obj class Person(metaclass=SingMeta):
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender def say(self):
print("my name is %s my 姑姑 is 龙妈" % self.name) class Student(metaclass=SingMeta):
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender=gender def 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 = None def __call__(self, *args, **kwargs):
if self.obj:
return self.obj obj = type.__call__(self,*args,**kwargs)
self.obj = obj
return obj class QQPlayer(metaclass=Single):
def __init__(self,voice_value,repeat=False):
self.voice_value =voice_value
self.repeat = repeat def play(self,file_path):
if hasattr(self,'file_path'):
self.stop() print('正在播放%s'%file_path)
self.file_path = file_path def 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[:]
# name
print("over")
except Exception:
print("不知道啥原因 反正有问题!") # 语法6 给异常对象取别名 从而访问一异常对象
# 之所以 能处理任何类型 是因为 Exception 是所有异常类的父类
try:
print("start")
# {"name":1}["xxx"]
1[:]
# name
print("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):
pass class 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")

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. c语言字符串操作总结(转)

    本文转自:http://www.jb51.net/article/37410.htm 1)字符串操作 strcpy(p, p1) 复制字符串 strncpy(p, p1, n) 复制指定长度字符串 s ...

  2. Linux网络编程函数

    1. Server端-socket/bind/listen/accept/read socket(AF_INET, SOCK_STREAM, 0); //指定端口,内核将端口上的数据转发给该socke ...

  3. Navicat for mysql远程连接数据库详解(1130错误解决方法)

    用Navicat for mysql连接数据库测试下连接 如果出现1130错误 错误代码是1130,ERROR 1130: Host xxx.xxx.xxx.xxx is not allowed to ...

  4. jquery选择器大全参考

    在Dom 编程中我们只能使用有限的函数根据id 或者TagName 获取Dom 对象. 然而在jQuery 中则完全不同,jQuery 提供了异常强大的选择器用来帮助我们获取页面上的对象, 并且将对象 ...

  5. maven(多个模块)项目 部署 开发环境 问题处理历程【异常Name jdbc is not bound in this Context 异常java.lang.NoSuchMethodE】

    maven(多个模块)项目 部署 开发环境 问题处理历程[异常Name jdbc is not bound in this Context 异常java.lang.NoSuchMethodE] 201 ...

  6. 获取hudson持续构建编译结果的一种方法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 很多时候使用hudson结合VisualStudio进行持续构建后需要获取持续构建的编译结果,通过编译结果来知道哪些项 ...

  7. CocoStudio UIButton setPressedActionEnabled(true) 子控件不跟着缩放

    具体情况是这样的:美术给了我 一个按钮的背景图片  一个按钮的文字图片,用背景图片创建一个button,然后把文字图片添加进去(注意关闭文字图片的交互功能) 设置UIButton setPressed ...

  8. Python http

    # import httplib # http_client = None # http_client = httplib.HTTPConnection('localhost', 8080, time ...

  9. SQL Server Profiler查询跟踪的简单使用

    1.打开SQL Server Management Studio,选择工具->SQL Server Profiler,或者直接从路径:开始/程序/Microsoft SQL Server 200 ...

  10. 忽略mysql库的同步

    忽略mysql库的同步,请使用: stop slave sql_thread; change replication filter replicate_ignore_db=(mysql);