It seems I was cheering a bit too early my success haha. It seems the AI agent decided to simply bypass the locking mechanism instead of making it work with constant values. Tool is running with insufficient ressources so it takes full days for it to execute anything. I love this setup where the agent is slow as it forces me to work manually as well. I strongly suggest it to any begginers, tandem work on dual project, one is manual and the other is slow but automatic. While the agent is finishing up the class lock, I'll work to figure out how class inheritance / metaclass fed to it can be detected or backtracked for guidance purposes. Didn't even knew class had this system so I'm still exploring and might be doing this for the whole day.
🟦 1. Basic Classes
A class in Python is just a template for creating objects.
class Animal:
def speak(self):
return "some sound"
a = Animal()
print(a.speak()) # "some sound"
🟦 2. Inheritance (Re-using / Extending Classes)
Inheritance means one class reuses or extends another.
class Dog(Animal): # Dog inherits from Animal
def speak(self):
return "woof!"
Dog gets everything from Animal.
If you don’t override, it just uses the parent’s methods.
If you override (def speak), your new version is used.
d = Dog()
print(d.speak()) # "woof!"
🔹 Multiple Inheritance
Python allows a class to inherit from multiple classes.
class Walker:
def move(self):
return "walking"
class Swimmer:
def move(self):
return "swimming"
class Duck(Walker, Swimmer):
pass
Now, which move() does Duck use?
Python resolves it using the Method Resolution Order (MRO) → a deterministic order of lookup.
duck = Duck()
print(duck.move())
# "walking", because Walker is listed first
print(Duck.__mro__)
# (<class '__main__.Duck'>, <class '__main__.Walker'>, <class '__main__.Swimmer'>, <class 'object'>)
🟦 3. Constructors (__init__)
When you do obj = ClassName(...), Python calls the class’s __init__ method.
Parent constructors can be called with super().
class Animal:
def __init__(self, name):
self.name = name
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name) # call parent __init__
self.breed = breed
d = Dog("Rex", "Labrador")
print(d.name, d.breed) # Rex Labrador
🟦 4. Metaclasses (Classes of Classes)
Now the tricky part:
In Python, everything is an object, even classes themselves.
If objects are created by classes… what creates classes?
→ The answer: a metaclass.
By default, Python uses type as the metaclass.
# "Animal" is itself an object created by "type"
print(type(Animal)) # <class 'type'>
So:
Normal objects are instances of a class.
Classes are instances of a metaclass (usually type).
🔹 Custom Metaclass
You can define your own metaclass to control how classes are built.
class Meta(type): # inherit from 'type'
def __new__(cls, name, bases, dct):
print(f"Creating class {name}")
return super().__new__(cls, name, bases, dct)
class MyClass(metaclass=Meta):
pass
Output:
Creating class MyClass
Here, Meta.__new__ runs at the moment the class is defined, not when it’s instantiated.
Metaclasses are like blueprints for classes.
🟦 5. When to Use Inheritance vs Metaclasses
Inheritance = organize and reuse code between objects.
Metaclasses = control or modify how classes themselves behave (rare, advanced use cases).
Example metaclass usage:
Enforcing coding standards (e.g., all methods must be lowercase).
Auto-registering classes into a plugin system.
Automatically adding methods/attributes to classes.
🟦 6. Summary
Inheritance:
Reuse code between classes.
Supports multiple parents.
Follows MRO for lookup.
Constructors (__init__):
Define what parameters a class instance takes.
super() allows chaining to parent constructors.
Metaclasses:
Classes are objects, created by a metaclass (type by default).
Custom metaclasses let you intercept or modify class creation.
Powerful, but niche — usually not needed unless building frameworks/libraries.
Wasn't too sure about how super() and metaclass usage so I keep going:
🟦 1. type as “the metaclass of metaclasses”
In Python:
Normally, when you call a class like Dog("Rex"), what happens is not a simple function call.
Internally, Python does something like this:
obj = Dog.__call__(*args, **kwargs)
But Dog.__call__ comes from its metaclass (by default, type).
So the whole flow is:
Dog(...)
→ Dog.__class__ is type
→ type.__call__(Dog, *args, **kwargs)
→ Dog.__new__(Dog, *args, **kwargs) # allocate memory
→ Dog.__init__(self, *args, **kwargs) # initialize fields
→ return instance
🟦 2. So what does super() really do?
super() doesn’t mean “the parent”. It means:
“go to the next class in the MRO after my current class.”
Example:
class A:
def greet(self):
print("A")
class B(A):
def greet(self):
print("B")
super().greet()
class C(A):
def greet(self):
print("C")
super().greet()
class D(B, C):
def greet(self):
print("D")
super().greet()
MRO:
print(D.__mro__)
# (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
Execution:
D().greet()
# D
# B
# C
# A
Notice how super() followed the MRO, not just “parent”.
🟦 3. Metaclasses in Action
If you give a class a metaclass=Meta, then the creation of the class object itself is intercepted.
class Meta(type):
def __call__(cls, *args, **kwargs):
print(f"Creating instance of {cls.__name__}")
return super().__call__(*args, **kwargs)
class MyClass(metaclass=Meta):
def __init__(self, x):
self.x = x
Now:
obj = MyClass(42)
Execution order:
Meta.__call__(MyClass, 42) runs
Inside, super().__call__ delegates to type.__call__
Which calls MyClass.__new__
Then MyClass.__init__
🟦 4. Why it looks “hardcoded”
Yes — you must declare metaclass=Meta because only one metaclass controls class creation.
But note:
class Foo: pass → uses type automatically.
class Foo(metaclass=Meta): pass → uses your Meta.
And since metaclasses are themselves subclasses of type, you can extend the logic of type.__call__, type.__new__, etc.
🟦 5. Analogy
Think of it like a factory system:
Objects = Products (instances you actually use).
Classes = Factories (blueprints for products).
Metaclasses = Factory Designers (blueprints for factories).
When you do:
p = Product()
it’s like:
Call the Factory Designer (metaclass) to create a Factory (class) → happens once at definition.
Call the Factory (class) to produce a Product (object) → happens each time you instantiate.
So here's a quick look under the hood of my learning process using GPT. I also sometime use Gemini through google search but it's usually for code snippets to validate syntax more than to learn new stuff. I hope you learned something as well. This learning experience opened my eyes to the power of Method Resolution Order (MRO).
- Use Class.mro to walk inheritance.
- If unresolved locally, parse imports to resolve base classes.
- Once you have class definitions, check init / new signatures → collect their parameter requirements.
- Detect metaclass= as the “entry point” to type class detection and can only have one declaration.
Top comments (2)
So you are studying how type() and classes in Python works under the hood to then use it for your own project right? That's interesting man I wouldn't have thought of that at this point in my learning journey, I just built small projects and now working on making more complex ones so maybe I will get to that point too haha, I hope it works out
yes indeed, one of my project is a code_checker so I need to understand most of how the synthax for different type of code. Although I'm not a big user of object oriented programming, sometime the usage of class objects is prefered. I personnally barely understand how they work so I'm reading about them, seems most of the parameters that can be given to a class are other class and they need to be somewhat used in a specific way for it to work properly. I think the biggest challenge of these code_checker projects is the ability to backtrack data that would be outside of the file scanned. For example: function(arg1, arg2): arg1 exist within the file but arg2 is not itinialized in the current script and needs to be found somehow with fairly limited knowledge about the project structure, so lots of recursive checks and state saving. Also im french, I'm doing my best to write in a comprehensible manner but sometime it might sound weird XD