Pregunta

He estado tratando de aprender acerca de las metaclases en Python. Tengo la idea principal, pero parece que no puedo activar el mecanismo. Como lo entiendo, puede especificar que M sea la metaclase cuando construya una clase K configurando __metaclass__ en M en el nivel global o de clase. Para probar esto, escribí el siguiente programa:

p = print

class M(type):
    def __init__(*args):
        type.__init__(*args)
        print("The rain in Spain")

p(1)
class ClassMeta:
    __metaclass__ = M

p(2)
__metaclass__ = M
class GlobalMeta: pass

p(3)
M('NotMeta2', (), {})

p(4)

Sin embargo, cuando lo ejecuto, obtengo el siguiente resultado:

C:\Documents and Settings\Daniel Wong\Desktop>python --version
Python 3.0.1

C:\Documents and Settings\Daniel Wong\Desktop>python meta.py
1
2
3
The rain in Spain
4

¿No debería ver "La lluvia en España"? después de 1 y 2? ¿Qué está pasando aquí?

¿Fue útil?

Solución

En Python 3 (que está utilizando) las metaclases están especificadas por un parámetro de palabra clave en la definición de la clase:

class ClassMeta(metaclass=M):
  pass

La especificación de una propiedad de clase __metaclass__ o una variable global es una sintaxis antigua de Python 2.x y ya no se admite. Consulte también " Novedades de Python 3 " y < a href = "http://www.python.org/dev/peps/pep-3115/" rel = "nofollow noreferrer"> PEP 2115 .

Otros consejos

Esto funciona como se espera en Python 2.6 (y versiones anteriores), pero en 3.0 las metaclases se especifican de forma diferente:

class ArgMeta(metaclass=M): ...

La sintaxis de las metaclases ha cambiado en Python 3.0. El atributo __metaclass__ ya no es especial ni en la clase ni en el nivel del módulo. Para hacer lo que intenta hacer, debe especificar metaclass como un argumento de palabra clave para la declaración de class :

p = print

class M(type):
    def __init__(*args):
        type.__init__(*args)
        print("The rain in Spain")

p(1)
class ClassMeta(metaclass=M): pass

Rendimientos:

1
The rain in Spain

Como es de esperar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top