python 元类
元类
# 定义类
class Foo(object):
def __init__(self, name):
self.name = name
def __new__(cls, *args, **kwargs):
data = object.__new__(cls)
return data
# 根据类创建对象
# 1.先执行类的__new__方法,创建对象(空对象)。 [构造方法] {}
# 2.执行类的__init__方法,初始化对象。 [初始化方法] {"name":"lem"}
obj = Foo("lem")
对象是基于类创建的。
问题:类是由谁创建的?
类默认是由type创建。
# 传统方式创建类
class Foo(object,metaclass=type): # 默认继承object,默认metaclass=type,可以不写
v1 = 123
def func(self):
return 666
print(Foo)=====><class '__main__.Foo'>
# 非传统方式(一行)
Fa = type('Foo', (object,), {'v1': 123, 'func': lambda self: 666})
# 创建者(类名,继承关系,成员)
print(Fa)=====><class '__main__.Foo'>
# 由谁创建就是实例化谁的对象,所以Fa就是type的实例化对象
def do(self):
pass
# 非传统方式(一行)
# 1.创建类型
# -类名 -继承关系 -成员
Fa = type('Foo', (object,), {'v1': 123, 'func': lambda self: 666, "do": do})
# 2.根据类创建对象
obj = Fa()
# 3.调用对象中v1变量(类变量)
print(obj.v1)
# 4.执行对象的func方法
res = obj.func()
print(res)
类默认由type创建,怎么让一个类的创建改成其他的东西?元类
元类:指定类由谁来创建。
# type创建Foo类型
class Foo(object,metaclass=type):
pass
# `东西` 创建Foo类型
class Foo(object,metaclass=`东西`):
pass
class F1:
def __init__(self):
print("init")
def __call__(self, *args, **kwargs):
print("call")
obj = F1() # 类加()会执行__new__和__init__方法
obj() # 对象加()会自动执行__call__方法
class MyType(type):
def __init__(self, *args, **kwargs):
print("MyType init")
super().__init__(*args, **kwargs)
def __new__(cls, *args, **kwargs):
# 创建类
print("MyType new")
# 调用自己类中的__new__方法
new_class = super().__new__(cls, *args, **kwargs)
return new_class
def __call__(self, *args, **kwargs):
print("MyType call")
# 1.调用你自己那个类的__new__方法去创建对象
empty_obj = self.__new__(self)
# 2.调用你自己那个类的__init__方法去初始化
self.__init__(empty_obj, *args, **kwargs)
return empty_obj
# 假设Foo是一个对象,由MyType创建。
# Foo类其实是MyType的一个对象
# Foo()————> MyType对象()
class Foo(object, metaclass=MyType):
def __init__(self, name):
print("Foo init")
self.name = name
def __call__(self, *args, **kwargs):
print("自己")
# Foo类由MyType创建
v1 = Foo('lem')
print(v1)
print(v1.name)
wtforms源码
from wtforms import Form
from wtforms.fields import simple
class FormMeta(type):
def __init__(cls, name, bases, attrs):
type.__init__(cls, name, bases, attrs)
cls._unbound_fields = None
cls._wtforms_meta = None
def __call__(cls, *args, **kwargs):
if cls._unbound_fields is None:
fields = []
for name in dir(cls):
if not name.startswith('_'):
unbound_field = getattr(cls, name)
if hasattr(unbound_field, '_formfield'):
fields.append((name, unbound_field))
# We keep the name as the second element of the sort
# to ensure a stable sort.
fields.sort(key=lambda x: (x[1].creation_counter, x[0]))
cls._unbound_fields = fields
# Create a subclass of the 'class Meta' using all the ancestors.
if cls._wtforms_meta is None:
bases = []
for mro_class in cls.__mro__:
if 'Meta' in mro_class.__dict__:
bases.append(mro_class.Meta)
cls._wtforms_meta = type('Meta', tuple(bases), {})
return type.__call__(cls, *args, **kwargs)
def with_metaclass(meta, base=object):
# FormMeta("NewBase",(BaseForm,), {})
# type("NewBase",(BaseForm,), {})
return meta("NewBase", (base,), {})
class NewBase(BaseForm, metaclass=FormMeta):
pass
class Form(NewBase):
pass
class Form(with_metaclass(FormMeta, BaseForm)):
pass
# LoginForm是由FormMeta 创建的。
# 1.创建类时,会执行 FormMeta的 __new__ 和 __init__ 内部在类中添加了两个类变量:cls._unbound_fields = None、cls._wtforms_meta = None
class LoginForm(Form):
name = simple.StringField(label='用户名', render_kw={'class': 'form-control'})
pwd = simple.PasswordField(label='密码', render_kw={'class': 'form-control'})
# 2.根据LoginForm去创建对象。 会先执行FormMeta.__call__方法
# 返回 return type.__call__(cls, *args, **kwargs)——>本质是调用LoginForm的__new__去创建对象,__init__去初始化对象
form = LoginForm()
print(form.name) # 类变量
print(form.pwd) # 类变量
# 问题1:此时的LoginForm是由 type or FormMeta创建?
"""
类中metaclass,自己类由metaclass定的类来创建
类继承某个类,父类metaclass,自己类由metaclass定义的类来创建
class NewBase(BaseForm, metaclass=FormMeta):
pass
class Form(NewBase):
pass
等价于
class Form(with_metaclass(FormMeta, BaseForm)):
pass
======>
所以Form是由父类NewBase的metaclass定义的类FormMeta创建
"""
学了元类之后,在:
- 类创建,自定义功能。
- 对象创建前后,自定义功能。
class MyType(type):
def __init__(self, *args, **kwargs):
# 创建类时,进行扩展
print("MyType init")
super().__init__(*args, **kwargs)
def __new__(cls, *args, **kwargs):
# 创建类时,进行扩展
print("MyType new")
# 调用自己类中的__new__方法
new_class = super().__new__(cls, *args, **kwargs)
return new_class
def __call__(self, *args, **kwargs):
# 创建对象时,进行扩展
print("MyType call")
# 1.调用你自己那个类的__new__方法去创建对象
empty_obj = self.__new__(self)
# 2.调用你自己那个类的__init__方法去初始化
self.__init__(empty_obj, *args, **kwargs)
return empty_obj
# 假设Foo是一个对象,由MyType创建。
# Foo类其实是MyType的一个对象
# Foo()————> MyType对象()
class Foo(object, metaclass=MyType):
def __init__(self, name):
print("Foo init")
self.name = name
# Foo类由MyType创建
v1 = Foo('lem')
print(v1)
单例模式
- 方式1:模块导入
- 方式2:并发编程
- 方式3:单例模式
class MyType(type):
def __init__(cls, name, bases, attrs):
super().__init__(name, bases, attrs)
cls.instance = None
def __call__(cls, *args, **kwargs):
# 1.判断是否已有对象,有,则不创建,没有则创建
if not cls.instance:
# 调用自己那个类的__new__创建对象
cls.instance = cls.__new__(cls)
# 2.调用你自己那个类的__init__方法去初始化
cls.__init__(cls.instance, *args, **kwargs)
return cls.instance
class Singleton(object, metaclass=MyType):
pass
class Foo(Singleton):
# # 类变量,创建的对象
# instance = None
pass
# print(Foo.instance)
# v1 = Foo()
"""
创建v1=Foo()时会先执行父类的创建类的__new__以及__init__方法初始化
此时Foo中instance=None接着Foo()会继续执行__call__方法
if not cls.instance: 判断是否已有对象
没有则cls.instance = cls.__new__(cls) 调用自己那个类的__new__创建对象
有则不创建对象
cls.instance = cls.__new__(cls) 调用你自己那个类的__init__方法去初始化
return cls.instance 最终返回该对象
"""
v1 = Foo() # 真正去创建对象并设置instance并返回
v2 = Foo()
print(v1) # 内存地址
print(v2) # 内存地址
>>>>>>>>
<__main__.Foo object at 0x000002A87F2DBFA0>
<__main__.Foo object at 0x000002A87F2DBFA0>
"==================================================================================="
class Foo(Singleton):
# # 类变量,创建的对象
# instance = None
def __init__(self, name):
self.name = name
v1 = Foo('lem') # 真正去创建对象并设置instance并返回
v2 = Foo('hina')
print(v1.name) # 内存地址
print(v2.name) # 内存地址
>>>>>>>>
hina
hina