知行编程网知行编程网  2022-11-27 23:30 知行编程网 隐藏边栏  13 
文章评分 0 次,平均分 0.0
导语: 本文主要介绍了关于详解Python元类(metaclass)的相关知识,包括meta类游戏,以及java的class这些编程知识,希望对大家有参考作用。


什么是元类?

理解元类(metaclass)之前,我们先了解下Python中的OOP和类(Class)。

Python元类(metaclass)详解


面向对象

全称 Object Oriented Programming 简称OOP,这种编程思想被大家所熟知。它是把对象作为一个程序的基本单元,把数据和功能封装在里面,能够实现很好的复用性,灵活性和扩展性。OOP中有2个基本概念:类和对象:




是描述如何创建一个对象的代码段,用来描述具有相同的属性和方法的对象的集合,它定义了该集合中每个对象所共有的属性和方法

对象是类的实例(Instance)。

我们举个例子:

In : class ObjectCreator(object):
...:     pass
...:
In : my_object = ObjectCreator()
In : my_object
Out: <__main__.ObjectCreator at 0x1082bbef0>

而Python中的类并不是仅限于此:

In : print(ObjectCreator)
<class '__main__.ObjectCreator'>

ObjectCreator是可以打印出来的,所以它的类也是一个对象!由于类是对象,因此你可以动态创建它们,就像任何对象一样。在日常工作中,有动态创建类的需求。例如,当模拟数据时,现在有一个函数 func 接收一个参数:

In : def func(instance):
...:     print(instance.a, instance.b)
...:     print(instance.method_a(10))
...:

正常使用时,传入的实例满足要求(有a、b属性和method_a方法),但是当我想单独调试func时,就需要“创建”一个。如果没有使用元类,应该这样写:

In : def generate_cls(a, b):
...:     class Fake(object):
...:         def method_a(self, n):
...:             return n
...:     Fake.a = a
...:     Fake.b = b
...:     return Fake
...:
In : ins = generate_cls(1, 2)()
In : ins.a, ins.b, ins.method_a(10)
Out: (1, 2, 10)

你会发现这不算算是「动态创建」的:


类名(Fake)不方便改变

需要创建的类的属性和方法越多,需要相应增加,不灵活。

我平时怎么做呢:

In : def method_a(self, n):
...:     return n
...: 
In : ins = type('Fake', (), {'a': 1, 'b': 2, 'method_a': method_a})()
In : ins.a, ins.b, ins.method_a(10)
Out: (1, 2, 10)

至此,type函数介绍完毕。最初它是用来让你知道一个对象的类型的:

In : type(1)
Out: int
In : type('1')
Out: str
In : type(ObjectCreator)
Out: type
In : type(ObjectCreator())
Out: __main__.ObjectCreator

另外type也可以像上面说的那样动态创建类:type可以把类的描述作为参数,返回一个类。

用来创建类的东东就是「元类」

MyClass = type('MyClass', (), {})

这种用法是由于 type 实际上是一个元类,而 type 作为元类在 Python 中用于在幕后创建所有类。 Python语言中有一句话“万物皆对象”。打包整数、字符串、函数和类……所有这些都是对象。它们都是由一个类创建的:

In : age = 35
In : age.__class__
Out: int
In : name = 'bob'
In : name.__class__
Out: str
...

现在,任何__class__中的特定__class__是什么?

In : age.__class__.__class__
Out: type
In : name.__class__.__class__
Out: type
...

如果需要,你可以将类型称为“类工厂”。 type是Python内置的元类,当然你也可以创建自己的元类。


创建自己的元类

Python2创建类的时候,可以添加一个__metaclass__属性:

class Foo(object):
    __metaclass__ = something...
    [...]

如果这样做,Python 将使用元类来创建类 Foo。 Python 将在类定义中查找 __metaclass__。如果找到它,Python 将使用它来创建对象类 Foo。如果没有找到,Python 将使用类型来创建类。

在Python3中语法改变了一下:

class Simple1(object, metaclass=something...):
    [...]

本质上是一样的。以4年前写分享的一个metaclass为例(只是推荐大家阅读

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

知行编程网
知行编程网 关注:1    粉丝:1
这个人很懒,什么都没写
扫一扫二维码分享