Pergunta

Eu tenho tentado aprender sobre metaclasses em Python. Tenho a idéia principal, mas eu não consigo ativar o mecanismo. Pelo que entendi, você pode especificar M para ser como o metaclass ao construir uma classe K, definindo __metaclass__ a M no nível global ou classe. Para testar isso, eu escrevi o seguinte 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)

No entanto, quando eu executá-lo, eu recebo o seguinte 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

eu não deveria ver "A chuva na Espanha" depois de 1 e 2? O que está acontecendo aqui?

Foi útil?

Solução

Em Python 3 (que você está usando) metaclasses são especificados por um parâmetro de palavra-chave na definição da classe:

class ClassMeta(metaclass=M):
  pass

A especificação de uma propriedade de classe __metaclass__ ou variável global é velha sintaxe de Python 2.x e não mais suportada. Veja também "O que há de novo no Python 3" e PEP 2115 .

Outras dicas

Isso funciona como esperado no Python 2.6 (e anteriores), mas em 3,0 metaclasses são especificados de forma diferente:

class ArgMeta(metaclass=M): ...

A sintaxe de metaclasses tem alterado em Python 3.0. O atributo __metaclass__ não é especial em qualquer classe, nem o nível de módulo. Para fazer o que você está tentando fazer, você precisa especificar metaclass como um argumento de palavra-chave para a declaração class:

p = print

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

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

Os rendimentos:

1
The rain in Spain

Como seria de esperar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top