参考:
使用元类 - 廖雪峰
首先 ,metaclass 是一个指定类创建时候的操作,他就像是一个特殊的继承,但是一般的继承都是继承的 类或者实例可以使用的方法或者属性,但是我们想在穿件类之前自动执行一些东西,这时候因为类还不存在呢,所以不能通过继承来实现了。有一种更贱单的方法,就是使用 元类,元类最后会继承 type 类,type 是 创建类的时候调用的函数,他是object 类的实例,因为 object 是所有类的基类,但同时 object 又是type 的实例,因为 type 是穿件类的类,二者互相关联。gg
type 类里面有个 --new--(cls, name, bases, attrs) 这个是穿件类的时候要调用的
new()方法接收到的参数依次是:
当前准备创建的类的对象
类的名字
类继承的集合
类的方法集合
一般我们定义类都是 写固定的 class ...这样都是静态代码,必须解释器执行的时候,要写好。写了就有这个类,不写就没有
如果想动态穿件类 ,就需要使用 type 了。其实平时写的class 穿件的时候,也是调用 type 来穿件的。
动态穿件 类:
... print('Hello, %s.' % name)
...
>>> Hello = type('Hello', (object,), dict(hello=fn)) # 创建Hello class
>>> h = Hello()
>>> h.hello()
Hello, world.
>>> print(type(Hello))
<class 'type'>
>>> print(type(h))
<class '__main__.Hello'>
要创建一个class对象,type()函数依次传入3个参数:
class的名称;
继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法;
class的方法名称与函数绑定,这里我们把函数fn绑定到方法名hello上。
关于 类穿件和实例穿件:
当我们定义了类以后,就可以根据这个类创建出实例,所以:先定义类,然后创建实例。
但是如果我们想创建出类呢?那就必须根据metaclass创建出类,所以:先定义metaclass (不写直接使用 type 了),然后创建类。
metaclass 其实和普通的装饰器,有很大的共同点。都是属于穿件或者使用之前进行某种额外的操作。只不过,metaclass 是默认类生成时调用,装饰器要手动写 @ 才行。 那么看来 metaclass 更像是一个语法糖了。
--new-- 和 --init-- 的区别,new 是类的初始化, init 是实例的初始化。
绝歌例子,使用 orm 元类。
相当于在类穿件的时候,元类里面的new 默认把当前类名当做数据表,写到了类的属性里面。并且提供了一系列的操作数据库的准备工作,实例生成的时候,就可以直接使用 类里面已经有的东西了。总体来说就是 把代码复杂度降低
单例模式:
class Singleton(object):
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = object.__new__(cls, *args, **kwargs)
return cls._instance
s1 = Singleton()
s2 = Singleton()
print(s1)
print(s2)
输出:
<__main__.Singleton object at 0x7fdef58b1190>
<__main__.Singleton object at 0x7fdef58b1190>
工厂模式
class Fruit(object):
def __init__(self):
pass
def print_color(self):
pass
class Apple(Fruit):
def __init__(self):
pass
def print_color(self):
print("apple is in red")
class Orange(Fruit):
def __init__(self):
pass
def print_color(self):
print("orange is in orange")
class FruitFactory(object):
fruits = {"apple": Apple, "orange": Orange}
def __new__(cls, name):
if name in cls.fruits.keys():
return cls.fruits[name]()
else:
return Fruit()
fruit1 = FruitFactory("apple")
fruit2 = FruitFactory("orange")
fruit1.print_color()
fruit2.print_color()
输出:
apple is in red
orange is in orange
网友评论