从创建类到创建实例的过程深刻理解元类
1. 创建类对象和创建实例对象的过程
class Cat(object):
# 类属性
name = '吉姆'
def eat(self):
print('%s在吃鱼'%self.name)
def drunk(self, name):
self.name = name
print('%s在喝水'%self.name)
tumao = Cat()
lanmao = Cat()
这段代码执行过程如下:
在Python中,类本质上也是对象,只不过这个对象拥有创建对象(实例)的能力。
2. 元类
- 所有类的元类——type类详解
type(类名,父类元组,包含属性的字典(类中的名称和值对)),比如:
1. 构建Foo类
class Foo(object):
bar = True
# 使用type构建,等同于
Foo = type('Foo', (), {'bar':True})
2. 构建FooChild继承Foo类
class FooChild(Foo):
pass
def echo_bar(self):
print self.bar
# 使用type构建FooChild类,并在此类中加入echo_bar方法
FooChild = type('FooChild', (Foo,), {'echo_bar':echo_bar})
- 自定义元类,从而在创建类的时候能自动改变类
(1)给当前类指定元类的两种方式
1. 第一种方式,通过__metaclass__指定
class Foo(object):
__metaclass__ = upper_attr
2. 第二种方式
class Foo(object, metaclass=upper_attr):
pass
【在类被定义的时候,还没有在内存中生成,直到被调用。Python此时做了如下操作:
1)检查Foo中是否由__metaclass__属性,如果找到了,就根据此属性创建一个名字为Foo的类对象
2)如果没有,检查Foo的父类
3)如果还没有,去模块层次中找
4)如果还是找不到,就用内建类type创建这个类】
(2)使用第一种方式指定元类时,创建元类的方法
def upper_str(future_class_name, future_class_parents, future_class_attr):
# 这个元类的功能是:在创建类的时候,保证类中的属性都是大写字母形式的
attrs = ((name, value) for name, value in future_class_attr.items() if not name.startswith('__'))
# 将这些属性转化成大写字母
uppercase_str = {name.upper(): value for name, value in attrs}
# 利用新转化的属性构建类
return type(future_class_name, future_class_parents, uppercase_attr)
class Foo():
__mataclass__ = upper_str
bar = 'bip'
(3)使用第二种方式指定元类时,创建元类的方法
# 创建一个类,此类一般以MetaClass结尾,继承自type类
class UpperAttrMetaClass(type):
# 如果指定元类,会调用类的__new__方法创建类对象
def __new__(cls, name, bases, attr):
attrs = ((name, value) for name, value in attr.items())
uppercase_attr = {name.upper: value for name, value in attrs}
return super(UpperAttrMetaClass, cls).__new__(cls, name, bases, uppercase_attr)
class Foo(metaclass=UpperAttrMetaClass):
pass
3. 单例模式的实现
- 什么是单例模式?
单例是一种设计模式,应用该模式的类指挥生成一个实例。保证了在程序的不同位置都可以且仅可以取到同一个对象实例。
举个实际例子,说明单例模式的应用场景:
有一款游戏软件,游戏中需要由“场景管理器”来管理游戏场景的切换、资源载入等任务,这个管理器类需要有多种方法和属性,在代码的很多地方都会调用,但不管在什么位置调用此管理器,都需要保证调用的是同一个管理器。
- 单例模式的四种实现方式
1. 实现方式一:函数装饰器/类装饰器
# 定义装饰器,装饰器修饰类的时候,只执行一次
def singleton(cls):
# 接收的cls是一个类对象
_instance = {}
def inner():
if cls not in _instance:
_instance[cls] = cls()
return _instance[cls]
return inner
@singleton
class Cls(object):
def __init__(self):
pass
cls1 = Cls()
cls2 = Cls()
print(id(cls1) == id(cls2))
2. 实现方式二:在__new__方法中干预
class Single():
_instance = None
def __new__(cls, *args, **kw):
if cls._instance is None:
cls._instance = object.__new__(cls, *args, **kw)
return cls._instance
def __init__(self):
pass
3. 实现方式三:元类
class Singleton(type):
def __init__(self, *args, **kw):
self._instance = None
def __call__(self, *args, **kw):
if self._instance is None:
self._instance = super(Singleton, self).__call__(*args, **kw)
return self._instance