Maison  >  Article  >  développement back-end  >  La création et l'utilisation de métaclasse en Python

La création et l'utilisation de métaclasse en Python

高洛峰
高洛峰original
2017-03-01 13:47:361492parcourir

En Python, nous pouvons utiliser la fonction type pour créer dynamiquement une métaclasse. Nous pouvons également utiliser l'attribut __metaclass__ pour spécifier une métaclasse. Ensuite, nous donnerons des exemples spécifiques pour expliquer la création et l'utilisation de métaclasses de métaclasse en Python

Les métaclasses vous permettent de définir comment certaines classes sont créées. Fondamentalement, cela vous donne le contrôle sur la façon dont vos classes sont créées.

La métaclasse est aussi une classe, une classe de types.

Les métaclasses sont généralement utilisées pour créer des classes. Lors de l'exécution d'une définition de classe, l'interpréteur doit connaître la métaclasse correcte pour cette classe. Si cet attribut n'est pas défini, il recherchera l'attribut __metaclass__ dans la classe parent. Si ce n'est pas encore trouvé, recherchez les variables globales.

Pour les classes traditionnelles, leur métaclasse est types.ClassType.

Les métaclasses ont également un constructeur, passant trois paramètres : le nom de la classe, un tuple de données héritées de la classe de base et un dictionnaire d'attributs de classe.
Ensuite, nous définissons une métaclasse, qui nécessite que lors de l'écriture d'une classe, une méthode __str__() soit fournie pour la classe. Si la méthode __repr__() n'est pas fournie,
vous donnera un avertissement.

from warnings import warn
#元类需要继承type类
class ReqStrSugRepr(type):
  def __init__(cls, name, bases, attrd):
  #构造函数需要传递的参数为类名,基类,类属性字典
    super(ReqStrSugRepr, cls).__init__(name, bases, attrd)
    # 判断__str__字符串是否在类的属性字典里
    if '__str__' not in attrd:
      raise TypeError('Class requires overriding of __str__()')

    if '__repr__' not in attrd:
      warn('Class suggests overriding of __repr__()\n', stacklevel=3)

class Foo(object):
  #给类指定元类 
  __metaclass__ = ReqStrSugRepr

  def foo(self):
    pass
#这一段代码不用创建类来测试,直接运行一下就会报错,可见元类的功力。

La création et lutilisation de métaclasse en Python



type

La fonction type peut vérifier le type d'une variable, telle que :

# <type &#39;int&#39;>
# <type &#39;str&#39;>
type(1)     
type(&#39;mink&#39;)

La fonction type peut également créer un new object

type accepte trois paramètres, name, bases, dict. Le premier accepte le nom de la classe, le deuxième paramètre accepte la classe parent (forme tuple) et le troisième paramètre accepte les attributs et méthodes (forme dictionnaire)

X = type(&#39;X&#39;, (object,), dict(a=1))
# 等于
class X(object):
  a = 1

Voici les méthodes qui acceptent les fonctions

def say(self):
  print &#39;hello&#39;

X = type(&#39;X&#39;, (object,), dict(say=say))
x = X()

# pirnt hello
x.say()

Métaclasse

Nous savons tous que les objets d'instance peuvent être créés via des classes, et les métaclasses sont des classes qui créent des objets de classe. Le type peut créer des objets de classe, ce qui signifie que le type est une métaclasse.

Attribut métaclasse

Si vous souhaitez utiliser une métaclasse pour créer un objet de classe, vous devez ajouter un attribut __metaclass__ à l'objet. Bien sûr, vous devez d'abord avoir une métaclasse

class PrivateMetaclass(type):
  def __new__(cls, name, parents, attrs):
    attrs = dict((&#39;__%s&#39; % k, v) for k, v in attrs.itmes())
    return super(PrivateMetaclass, cls).__new__(cls, name, parents, attrs)

class A(object):
  __metaclass__ = PrivateMetaclass
  a = 1
  b = 2

a = A()
# raise AttributeError
print a.a, a.b 

# print 1, 2
print a.__a, a.__b

afin de pouvoir modifier certaines fonctionnalités de la classe via la métaclasse. les variables doivent être des variables privées.


Pour plus d'articles liés à la création et à l'utilisation de métaclasses en Python, veuillez faire attention au site Web PHP chinois !

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn