python元类 orm_〖Python进阶〗从0到1编写ORM(一)元类详解

对象关系映射(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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值