Run Methods Order In Python

- 1. Understanding Python Classes
- 2. Dynamic Class Creation
- 3. Invisible Metaclasses In Python
- 4. Metaclasses In Python
- 5. namespace['attr'] = 1
- 6. Logging Namespace
- 7. Meta Classes Without Type
- 8. More Accurate Meta Classes Without Type
- 9. Run Methods Order In Python
- 10. Run Methods Order In Python With More Explanation
- 11. Register Classes in Python
- 12. Singleton in Python
- 13. Modeling a Class with a Metaclass
- 14. Define Method If Condition True
Run Methods Order In Python
Bir metaclass tanımlanırken hangi metodun ne zaman tetiklendiğini anlamak, metaclass yazımının en kritik parçasıdır. Aşağıdaki kod her metodun başına print ekleyerek çalışma sırasını görünür kılar:
class Meta(type):
@classmethod
def __prepare__(mcs, cls_name, bases, **kwargs): # default, staticmethod
print("Meta.__prepare__")
return super().__prepare__(cls_name, bases)
def __new__(mcs, cls_name, bases, namespace, **kwargs):
print(f"Meta.__new__")
return super().__new__(mcs, cls_name, bases, namespace)
def __init__(cls, cls_name, bases, namespace, **kwargs):
print(f"Meta.__init__")
super().__init__(cls_name, bases, namespace, **kwargs)
def __call__(cls, *args, **kwargs):
print(f"Meta.__call__")
return super().__call__(*args, **kwargs)
class Base:
pass
class Example(Base, metaclass=Meta): # Order: Meta.__prepare__, Meta.__new__, Meta.__init__
# def __prepare__(mcs, cls_name, bases): # it doesn't work, in this way
def __new__(cls, *args, **kwargs):
print(f"Example.__new__")
return super().__new__(cls)
def __init__(self):
print(f"Example.__init__")
def __call__(self, *args, **kwargs):
print(f"Example.__call__")
base = Example() # Meta.__call__, Example.__new__, Example.__init__
base() # Example.__call__Çalışma Sırası
Sınıf tanımlanırken (class Example(Base, metaclass=Meta): satırı okunduğunda):
Meta.__prepare__ ← namespace dict'i hazırlanır
Meta.__new__ ← sınıf nesnesi oluşturulur
Meta.__init__ ← sınıf nesnesi başlatılırÖrnek oluşturulurken (base = Example()):
Meta.__call__ ← metaclass'ın __call__'u tetiklenir (super().__call__ çağrılır)
Example.__new__ ← örnek nesnesi oluşturulur
Example.__init__ ← örnek nesnesi başlatılırÖrnek çağrılırken (base()):
Example.__call__ ← nesne callable olduğu için kendi __call__'u tetiklenir__prepare__ Neden @classmethod?
__prepare__ sınıf henüz oluşturulmadan önce çağrılır; dolayısıyla self olarak bir sınıf örneği alamaz. @classmethod ile metaclass’ın kendisini (mcs) alır. İnce bir ayrıntı: __prepare__ yorumda belirtildiği gibi sınıf gövdesinde tanımlanamaz — sadece metaclass üzerinde çalışır.
Hakan Çelik
