I'd like to know the reasoning why there are two different classes used, instead of just using Class for both.
Dataclasses provides many features that allow you to easily work with classes that act as data containers. In particular, this module helps to: write less boilerplate code. represent objects in a readable format.
In object-oriented programming, a metaclass is a class whose instances are classes. Just as an ordinary class defines the behavior of certain objects, a metaclass defines the behavior of certain classes and their instances. Not all object-oriented programming languages support metaclasses.
Every object and class in Python is either an instance of a class or an instance of a metaclass. Every class inherits from the built-in basic base class object , and every class is an instance of the metaclass type .
type is a metaclass, of which classes are instances. Just as an ordinary object is an instance of a class, any new-style class in Python, and thus any class in Python 3, is an instance of the type metaclass.
The short answer is "Your assumption that Classes are instances of a system wide Class is wrong, each Class is actually an instance of a Class specific Metaclass" and also "it wouldn't work any other way".
A slight modification to the answer is "the names are really confusing, it's sometimes easier to just memorize their roles and not try to think too much about how they work".
Short hairy answer:
Metaclass is an instance, just like all other ordinary Smalltalk Classes, and it requires it's own dedicated class. Each instance of a regular Smalltalk object has a class, with inheritance following the class hierarchy. Each class is itself an instance of a class specific metaclass, with inheritance following the metaclass hierarchy. Each metaclass is itself an instance of the Metaclass class, which is short-circuited by the virtual machine in a neat little trick, since no one has found a use to giving the Metaclass class a parent, and all those who tried have generally found that their sanity was starting to erode in the process.
Longer, still hairy answer:
Smalltalk allows for each class to contain class specific messages. These are equivalent, roughly, to static methods in Java - but with some significant differences. One of these differences is that Smalltalk classes are actually instantiated objects - they are live objects in the system, complete with the ability to inherit from other objects, and to contain instance variables.
This property leads to a potential multitude of inheritance hierarchies in the system. Regular objects each are instances of exactly one Class, with message sends to an objects searching the objects' class, and then following up the inheritance chain of the Class hierarchy. Messages sent to regular objects are resolved up the Class hierarchy.
Also, class objects are each instances of one class specific Metaclass. Messages sent to a class object are resolved by lookups to the class specific metaclass, and then upwards on the metaclass hierarchy.
Up one more layer, metaclass objects each are instances of a system wide unique Metaclass class. Messages sent to a metaclass object are looked up in the system-wide unique Metaclass, which is not allowed to inherit from anybody and is hard-wired as a short circuit in the VM.
Technically, the system has two inheritance hierarchies, and a third one that is faked with a short circuit. There's no theoretical reason to stop at two, though there are lots of practical ones. This allows each object to have it's own, object unique, messages, each class to have it's own, class unique, messages, and forces all Metaclasses to answer to just one set of messages, defined in the Metaclass.
Neat, huh?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With