对象关系映射(Object Relational Mapping,简称ORM)是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。
本节知识:
Python元类详解
在Python中,类也是一种对象,这个对象(类)拥有创建对象(类实例)的能力,而这就是为什么它是一个类的原因。但是,它的本质仍然是一个对象:
你可以将它赋值给一个变量
你可以拷贝它
你可以为它增加属性
你可以将它作为函数参数进行传递
>>> class One(): # 定义一个类(本身也是对象,类名就是对象名)
... pass
...
>>> print(One)
>>> One.a=123 # 给类增加属性
>>> one = One() # 创建一个(类实例)对象
>>> one.a
123
>>> print(one)
>>>
因为类是一个对象,所以也可以动态创建一个类
>>> def create_class(name):
... if name == 'A':
... class A():
... pass
... return A # 返回的是类,不是类的实例
... else:
... class B():
... pass
... return B
...
>>> A = create_class('A') # 函数返回一个类
>>> a = A() # a 是根据类A实例化的一个对象
>>> a
<__main__.create_class.>.A object at 0x10ca5d>
由于类也是对象,所以它们必须是通过什么东西来生成的。当使用class关键字时,Python解释器自动创建这个对象,Python也提供了手动处理的方法, 内建的type函数除了获取类型,也可以用来动态的创建一个类。
格式如下:
type(类名, 父类的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))
创建一个类,该类拥有一个属性和一个方法
>>> A = type('A',(),{'str':'Hello,World','say':(lambda self, str: print(str))})
>>> A # 利用type函数动态创建一个类
>>> a = A()
>>> a.say(a.str)
Hello,World
>>>
上述代码等价于
class A():
str = "Hello,World"
def say(self, str):
print(str)
关于元类(MetaClass),可以理解为 元类是类的类。元类的作用是用来创建类的。
MyClass = MyMetaClass()
MyObject = MyClass()
函数type实际上是一个元类,在Python中,所有的东西都是对象。这包括整数、字符串、函数以及类,而且它们都是从一个类创建而来。
>>> type.__class__
对于一个类来说,Python会在类的定义中寻找__metaclass__属性,如果找到了,Python就会用它来创建类,如果没有找到,就会用内建的type来创建这个类, 因此,可以自定义元类。
举例:
# 定义一个元类,用于拦截修改类
class BaseMetaClass(type):
# __new__ 是在__init__之前被调用的特殊方法
# 用来创建对象并返回的方法
def __new__(cls, name, bases, attrs):
attrs['content'] = attrs['content']+" 被元类修改了!"
attrs['str'] = 'Hello,World'
attrs['say'] = lambda self, str : print(str)
return type.__new__(cls, name, bases, attrs)
# 声明类A的 metaclass
class A(metaclass=BaseMetaClass):
content = "在类A中定义的内容"
# Python解释器首先在当前类的定义中查找metaclass,如果没有找到,就继续在父类中查找metaclass
# 如果在父类中找到了,就使用父类中定义的metaclass来创建该类
# 结论:metaclass可以隐式地继承到子类,但子类自己却感觉不到
class B(A):
content = "在类B中定义的内容"
a = A()
b = B()
a.say(a.str)
print(a.content)
print(b.content)
运行结果:
Hello,World
在类A中定义的内容 被元类修改了!
在类B中定义的内容 被元类修改了!
就元类本身而言,概括以下功能:
拦截类的创建
修改类
返回修改之后的类
“元类就是深度的魔法,99%的用户应该根本不必为此操心。如果你想搞清楚究竟是否需要用到元类,那么你就不需要它。那些实际用到元类的人都非常清楚地知道他们需要做什么,而且根本不需要解释为什么要用元类。”
—— Tim Peters