exec
参数1:字串形式命令
参数2:全局作用域(字典形式),如果不指定默认就使用globals()
参数3:局部作用域(字典形式),如果不指定默认就使用locals()
g = {"x":1,"y":2}
l = {}
exec('''
global x,m
x=10
m=100
z = 3''',g,l) # 引号中产生一个变量,变量放到局部作用域中
print(g)
print(l)
引号中产生一个变量,变量放到局部作用域中
python中一切皆对象。
对象使用:
1、都可以被引用,x=obj
2、都可以当做函数的参数传入
3、都可以当做函数的返回值
4、都可以当做容器类的元素(列表、元组、字典、集合,可以装多种值)
元类
产生类的类称之为元类,默认用class定义的类,他们的元类是type
定义类的两种方式:
方式一:class
class Chinese(objext,metaclass = type): # Chinese = type(...) metaclass元类
country = "China"
def __init__(self,name,age):
self.name = name
self.age = age
def talk(self):
print("%s is talking" %self.name)
方式二:type
定义类的三要素:类名、类的基类们。类的名称空间
类名(字符串):class_name = "Chinese"
继承(元组形式):class_bases = (object,)
类体(定义阶段类体代码立即执行)类的名称空间(字典形式):class_dic
# 类的名称空间的产生
class_body ='''
country = "China"
def __init__(self,name,age):
self.name = name
self.age = age
def talk(self):
print("%s is talking" %self.name)
'''
class_dic = {}
exec(class_body,globals(),class_dic)
print(class_dic)
#实例化
Chinese = type(class_name,class_bases,class_dic) # 实例化元类,得到元类的对象(就是用class声明的类)
自定义元类,控制类的行为
class Foo:
"""注释"""
pass
print(Foo.__dict__)
#__doc__ 存放注释信息
class Mymeta(type):
def __init__(self,class_name,class_bases,class_dic):
if not class_name.istitle(): # 判断类名首字母有无大写(自定义)
raise TypeError("类名首字母必须大写")
if '__doc__' not in class_dic or not class_dic["__doc__"].strip(): # 判断有无注释
raise TypeError("必须有注释且注释不能为空")
super(Mymeta,self).__init__(class_name,class_bases,class_dic)
class Chinese(object,metaclass = Mymeta):
"""自定义元类"""
country = "China"
def __init__(self,name,age):
self.name = name
self.age = age
def talk(self):
print("%s is talking" %self.name)
自定义元类,控制实例化的行为
__call__
# __call__方法 调用对象会触发__call__,将对象本身连同参数一起传入该方法中。
__call__控制类的实例化行为
__init__控制类的创建行为
class Foo:
def __call__(self, *args, **kwargs):
print(self)
print(args)
print(kwargs)
obj = Foo()
obj(1,2,3,a=1,b=2,c=3) # obj.__call__(obj,1,2,3,a=1,b=2,c=3)
<__main__.Foo object at 0x000002C36C7F0358>
(1, 2, 3)
{'a': 1, 'b': 2, 'c': 3
元类内部也应该有一个__call__方法,会在调用Foo时触发执行
Foo(1,2,x=1) # Foo.__call__(Foo,1,2,x=1)
class Mymeta(type):
def __init__(self,class_name,class_bases,class_dic):
if not class_name.istitle(): # 判断类名首字母有无大写(自定义)
raise TypeError("类名首字母必须大写")
if '__doc__' not in class_dic or not class_dic["__doc__"].strip(): # 判断有无注释
raise TypeError("必须有注释且注释不能为空")
super(Mymeta,self).__init__(class_name,class_bases,class_dic)
def __call__(self, *args, **kwargs):
print(self) # self= Chinese
print(args) # args=('alex',)
print(kwargs) # kwargs={'age': 18}
class Chinese(object,metaclass = Mymeta):
"""自定义元类"""
country = "China"
def __init__(self,name,age):
self.name = name
self.age = age
def talk(self):
print("%s is talking" %self.name)
obj = Chinese("alex",age=18) # Chinese.__call__(Chinese,"alex",18)
<class '__main__.Chinese'>
('alex',)
{'age': 18}
控制类的实例化行为
class Mymeta(type):
def __init__(self,class_name,class_bases,class_dic):
if not class_name.istitle(): # 判断类名首字母有无大写(自定义)
raise TypeError("类名首字母必须大写")
if '__doc__' not in class_dic or not class_dic["__doc__"].strip(): # 判断有无注释
raise TypeError("必须有注释且注释不能为空")
super(Mymeta,self).__init__(class_name,class_bases,class_dic)
def __call__(self, *args, **kwargs): #obj = Chinese("alex",age=18)
# print(self) # self= Chinese
# print(args) # args=('alex',)
# print(kwargs) # kwargs={'age': 18}
# 第一步:创造一个空对象
obj = object.__new__(self)
# 第二部:初始化obj
self.__init__(obj,*args, **kwargs)
# 第三部:返回obj
return obj
class Chinese(object,metaclass = Mymeta):
"""自定义元类"""
country = "China"
def __init__(self,name,age):
self.name = name
self.age = age
def talk(self):
print("%s is talking" %self.name)
obj = Chinese("alex",age=18) # Chinese.__call__(Chinese,"alex",18)
print(obj.__dict__)
{'name': 'alex', 'age': 18}
自定义元类控制类的实例化行为的应用
单例模式 参数一样,不要再新生新的内存空间
实现方式1:
class MySQL:
__instance = None
def __init__(self):
self.host = "127.0.0.1"
self.port = 3306
@classmethod
def singleton(cls):
if not cls.__instance: #没有就创建
obj = cls()
cls.__instance = obj
return cls.__instance
def conn(self):
pass
def execute(self):
pass
obj1 = MySQL.singleton()
obj2 = MySQL.singleton()
print(obj1 is obj2)
True
实现方式2:通过元类实现
class Mymeta(type):
def __init__(self,class_name,class_bases,class_dic): #控制类的创建行为
if not class_name.istitle(): # 判断类名首字母有无大写(自定义)
raise TypeError("类名首字母必须大写")
if '__doc__' not in class_dic or not class_dic["__doc__"].strip(): # 判断有无注释
raise TypeError("必须有注释且注释不能为空")
super(Mymeta,self).__init__(class_name,class_bases,class_dic)
self.__instance = None
def __call__(self, *args, **kwargs): #控制类的实例化行为
# 第一步:创造一个空对象
if not self.__instance:
obj = object.__new__(self)
# 第二部:初始化obj
self.__init__(self)
self.__instance = obj
# 第三部:返回obj
return self.__instance
class Mysql(object,metaclass=Mymeta):
"""自定义元类控制类的实例化行为的应用"""
__instance = None
def __init__(self):
self.host = "127.0.0.1"
self.port = 3306
@classmethod
def singleton(cls):
if not cls.__instance: #没有就创建
obj = cls()
cls.__instance = obj
return cls.__instance
def conn(self):
pass
def execute(self):
pass
obj1 = Mysql.singleton()
obj2 = Mysql.singleton()
print(obj1 is obj2)
True