简介
元类, 一个神奇的概念, 从陌生到熟悉到深陷其魅力仅仅花费我3天时间.
元类是什么?
维基百科说, 元类是一种实体的类的类, 普通的类定义特定实体的属性及行为, 元类定义特定的类的属性及行为.
python说, 元类是继承自type
的类.
owef说, 元类是ORM框架、自动切换代理IP、单例模式等场景中常见的一种类.
为了更好的理解并应用元类, 必须懂其意、知其形、善其变, 方可称大师.
(本文非入门贴, 近用于记录元类的相关知识和应用场景)
文章目录
- 预备知识
- 使用场景
- 参考链接
预备知识
- 基础概念
- 类内置方法
基础概念
1.python中一切对象都是type
类型的子类型, 包括: int
、str
、set
等
2.元类是由type
衍生而出, 所以调用元类的类需要先继承自一个type
(自定义类, object
, dict
, list
, set
, int
, str
等), python3默认继承自object
, 所以无需显示指定.
3.元类的结构变更操作都在元类的__new__()
方法中完成的
类内置方法的作用及调用顺序
1.__new__()
、__init__(self)
、__call__(self)
__new__()
负责创建一个实例对象, 在调用类创建对象时, 该方法作为一个类方法被自动调用. 如果该方法返回了一个实例, 实例会自动调用__init__(self)
方法对实例进行初始化; 如果无返回值或返回的不是一个实例, 返回值将不会自动调用__init__(self)
方法
2.__init__(self)
负责对new返回的实例对象进行实例属性的初始化
3.__call__(self)
负责实例化对象的函数调用, 在实例化对象被作为函数调用时会调用该方法
综上所述, 类内置方法的调用顺序为: __new__()
、__init__(self)
、__call__(self)
元类使用最佳场景
- 单例模式
ORM
框架- 爬虫自动设置IP代理
元类可将一组类的公共属性、方法进行封装,节省子类创建方法时的开销
元类实现单例模式
tips: __new__()
方法为类方法, 主要负责改变类的结构, 如预制一些通用函数、改变类的数据结构(tuple
、list
、dict
、set
等), 除个别的场景外, 不需要重写__new__
方法.
单例模式的核心是在类中定义一个属性_instance
用于存储类的唯一实例化的对象, 如果_instance
对象不为空则直接返回实例化对象, 否则创建实例化对象并赋值给_instance
属性1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class Singleton(type):
def __init__(self, *args, **kwargs):
super(Singleton, self).__init__(*args, **kwargs)
def __call__(cls, *args, **kwargs):
if not hasattr(cls, "_instance"):
cls._instance=super(Singleton, cls).__call__(*args, **kwargs)
return cls._instance
class Spider(metaclass=Singleton):
def __call__(cls):
return cls._instance
s1=Spider()
s2=Spider()
print(s1())
print(s2())
单例模式构造的类, 在同一个python运行时上下文中, 不论出现在几个模块中, 均只有一个实例化对象.
Django的ORM
框架
爬虫自动设置代理IP
参考文章
https://www.cnblogs.com/tkqasn/p/6524879.html
https://stackoverflow.com/questions/100003/what-are-metaclasses-in-python
http://blog.jobbole.com/21351/
https://jfine-python-classes.readthedocs.io/en/latest/index.html
http://python.jobbole.com/88795/?utm_source=blog.jobbole.com&utm_medium=relatedPosts
http://python.jobbole.com/85126/?utm_source=blog.jobbole.com&utm_medium=relatedPosts
http://python.jobbole.com/86248/?utm_source=blog.jobbole.com&utm_medium=relatedPosts
http://python.jobbole.com/86821/?utm_source=blog.jobbole.com&utm_medium=relatedPosts
http://python.jobbole.com/86566/?utm_source=blog.jobbole.com&utm_medium=relatedPosts