2009-05-04 18 views
6

Próbowałem dowiedzieć się o metaclasses w Pythonie. Mam główny pomysł, ale nie mogę aktywować mechanizmu. Jak rozumiem, możesz określić M jako metaklas podczas konstruowania klasy K, ustawiając __metaclass__ na M na poziomie globalnym lub klasowym. Aby to przetestować, napisałem poniższy program:Nie powinno __metaclass__ wymuszać użycia metaclass w Pythonie?

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) 

Jednak, kiedy go uruchomić, pojawia się następujący komunikat:

 
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 

nie powinienem widzieć „Deszcz w Hiszpanii” po 1 i 2? Co tu się dzieje?

+1

Podwójne negatywne "nie ... nie wymusza" jest trudne do przeanalizowania. Mógłbyś to naprawić? –

+0

Dzięki za opinię. Myślę, że teraz powinno być łatwiej zrozumieć. – allyourcode

Odpowiedz

13

W Pythonie 3 (którego używasz) metaclasses są określone przez parametr słowo kluczowe w definicji klasy:

class ClassMeta(metaclass=M): 
    pass 

określenie właściwości __metaclass__ klasa lub zmiennej globalnej jest stary składnia z Pythona 2.x, a nie dłużej obsługiwane. Zobacz także "What's new in Python 3" i PEP 2115.

2

Działa to jak można się spodziewać w Pythonie 2.6 (i wcześniejszych), ale w 3,0 metaclasses podano inaczej:

class ArgMeta(metaclass=M): ... 
2

Składnia metaclasses ma changed w Pythonie 3.0. Atrybut __metaclass__ nie jest już specjalny na poziomie klasy ani modułu. Aby zrobić to, co próbujesz zrobić, trzeba określić metaclass jako argument słowo kluczowe aby rachunku class:

p = print 

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

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

Wynik:

1 
The rain in Spain 

Jak można się spodziewać.