📜  如何创建在 Python2 和 Python3 上运行的元类实例?

📅  最后修改于: 2022-05-13 01:54:37.261000             🧑  作者: Mango

如何创建在 Python2 和 Python3 上运行的元类实例?

元类是生成其他类的类。它是一个有效的类验证工具,可以防止子类继承某些类的函数,动态生成类。在这里,我们将讨论如何创建一个可以在Python 2 和Python 3 上运行的元类的实例。在深入研究之前,让我们先了解一下每个Python版本的代码设计。

Python3

在Python 3 中,通过将元类提供给元类关键字参数,在声明类时创建元类的实例。让我们看看在Python 3 中执行此操作的首选方法。

Python3
class MetaCls(type):
  def __new__(cls, name, bases, attrs):
    return super(MetaCls, cls).__new__(cls, name, bases, attrs)
    
class C(object, metaclass=MetaCls):
  pass
  
print('Type of class C:',type(C))


Python
class MetaCls(type):
  def __new__(cls, name, bases, attrs):
    return super(MetaCls, cls).__new__(cls, name, bases, attrs)
    
class C(object):
  __metaclass__ = MetaCls
    
print(type(C))


Python3
import six
  
class MetaCls(type):
  def __new__(cls, name, bases, attrs):
    return super(MetaCls, cls).__new__(cls, name, bases, attrs)
    
class C(six.with_metaclass(MetaCls)):
  pass
  
print(type(C))


Python3
import six
  
class MetaCls(type):
  def __new__(cls, name, bases, attrs):
    return super(MetaCls, cls).__new__(cls, name, bases, attrs)
    
@six.add_metaclass(MetaCls)
class C(object):
  pass
  
print(type(C))


输出
Type of class C: 

在这里,我们通过为metaclass关键字参数提供MetaCls类,创建了一个名为C的类。您可以将C类的类型视为MetaCls。

注意:MetaCls 是一个直接继承自 type 的元类

Python2

现在,让我们看看如何在Python 2 中创建元类的实例。在Python 3 中,我们已经看到在类声明的关键字参数中提到了元类;而在Python 2 中,元类是通过使用 __metaclass__ 属性在类体中分配的。让我们看看下面的代码:

Python

class MetaCls(type):
  def __new__(cls, name, bases, attrs):
    return super(MetaCls, cls).__new__(cls, name, bases, attrs)
    
class C(object):
  __metaclass__ = MetaCls
    
print(type(C))
输出

在Python 2 和Python 3 上运行的元类代码

现在很清楚Python 2 和Python 3 中的语法有何不同。如果您尝试将Python 2 代码迁移到Python 3,这种语法差异可能会造成麻烦。由于Python 3 向后不兼容,因此Python 3 语法不会执行在Python 2 上,反之亦然。

一个名为6的工具的重要性由此而来。它提供了两种方法来声明元类以确保交叉兼容性。

  1. 通过创建一个替身类
  2. 作为装饰者

在第一种方法中,我们将创建一个替代类并将其用作直接子类。让我们看看下面的代码。

蟒蛇3

import six
  
class MetaCls(type):
  def __new__(cls, name, bases, attrs):
    return super(MetaCls, cls).__new__(cls, name, bases, attrs)
    
class C(six.with_metaclass(MetaCls)):
  pass
  
print(type(C))
输出

现在,让我们看看如何使用装饰器创建元类的实例。

蟒蛇3

import six
  
class MetaCls(type):
  def __new__(cls, name, bases, attrs):
    return super(MetaCls, cls).__new__(cls, name, bases, attrs)
    
@six.add_metaclass(MetaCls)
class C(object):
  pass
  
print(type(C))
输出