<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Classes are objects in Python.
I like to take examples from one programming language and attempt to use them in another.
I asked myself if Python code could be written to imitate JavaScript's prototypical inheritence where prototypical inheritence is defined as
Step1:  creates in memory an object with the name "ObjectCreator".
Step2:  But still, it's an object, and therefore
Step3:  you can copy it
Step4:  you can add attributes to it
Step5:  you can pass it as a function parameter
Step6:  But it's not so dynamic, since you still have to write the whole class yourself.
Since classes are objects, they must be generated by something.
When you use the class keyword, Python creates this object automatically. But as with most things in Python, it gives you a way to do it manually.
Remember the function type? The good old function that lets you know what type an object is
Step7:  Well, type has a completely different ability, it can also create classes on the fly. type can take the description of a class as parameters, and return a class.
Step8:  type accepts a dictionary to define the attributes of the class. So
Step9:  Eventually you'll want to add methods to your class. Just define a function with the proper signature and assign it as an attribute.
Step10:  You see where we are going
Step11:  You define classes in order to create objects, right?
But we learned that Python classes are objects.
Step12:  Changing to blog post entitled Python 3 OOP Part 5—Metaclasses
object, which inherits from nothing.
reminds me of Eastern teachings of 'sunyata'
Step13:  Metaclasses are a very advanced topic in Python, but they have many practical uses. For example, by means of a custom metaclass you may log any time a class is instanced, which can be important for applications that shall keep a low memory usage or have to monitor it.
Step14:  The constructor mechanism in Python is on the contrary very important, and it is implemented by two methods, instead of just one
Step15:  Subclassing int
Object creation is behaviour. For most classes it is enough to provide a different __init__ method, but for immutable classes one often have to provide a different __new__ method.
In this subsection, as preparation for enumerated integers, we will start to code a subclass of int that behave like bool. We will start with string representation, which is fairly easy.
Step16:  The solution to the problem is to use new. Here we will show that it works, and later we will explain elsewhere exactly what happens.
<ASSISTANT_TASK:>
Python Code:
from pprint import pprint
%%HTML
<p style="color:red;font-size: 150%;">Classes are more than that in Python. Classes are objects too.</p>
%%HTML
<p style="color:red;font-size: 150%;">Yes, objects.</p>
%%HTML
<p style="color:red;font-size: 150%;">As soon as you use the keyword class, Python executes it and creates an OBJECT. The instruction</p>
class ObjectCreator(object):
    pass
Explanation: Classes are objects in Python.
I like to take examples from one programming language and attempt to use them in another.
I asked myself if Python code could be written to imitate JavaScript's prototypical inheritence where prototypical inheritence is defined as:
…when an object inherits from another object. This differs from classical inheritance, in which a class inherits from another class.
—https://www.quora.com/What-is-prototypal-inheritance
Classes are in indeed objects in Python so in a way Python classes are objects that ineed do, too, inherit from other objects. It just isn't implemented exactly the same in JavaScript.
I did find a blog post about writing a Python library that has objects behaving like JavaScript objects.
The material below is adapted from from What is a metaclass in Python?
Python has a very peculiar idea of what classes are, borrowed from the Smalltalk language.
End of explanation
%%HTML
<p style="color:red;font-size: 150%;">This object (the class) is itself capable of creating objects (the instances), and this is why it's a class.</p>
Explanation: creates in memory an object with the name "ObjectCreator".
End of explanation
object_creator_class = ObjectCreator
print(object_creator_class)
Explanation: But still, it's an object, and therefore:
you can assign it to a variable
End of explanation
from copy import copy
ObjectCreatorCopy = copy(ObjectCreator)
print(ObjectCreatorCopy)
print("copy ObjectCreatorCopy is not ObjectCreator: ", ObjectCreatorCopy is not ObjectCreator)
print("variable object_creator_class is ObjectCreator: ", object_creator_class is ObjectCreator)
Explanation: you can copy it
End of explanation
print("ObjectCreator has an attribute 'new_attribute': ", hasattr(ObjectCreator, 'new_attribute'))
ObjectCreator.new_attribute = 'foo' # you can add attributes to a class
print("ObjectCreator has an attribute 'new_attribute': ", hasattr(ObjectCreator, 'new_attribute'))
print("attribute 'new_attribute': ", ObjectCreator.new_attribute)
Explanation: you can add attributes to it
End of explanation
def echo(o):
    print(o)
# you can pass a class as a parameter
print("return value of passing Object Creator to {}: ".format(echo), echo(ObjectCreator)) 
%%HTML
<p style="color:red;font-size: 150%;">Since classes are objects, you can create them on the fly, like any object.</p>
def get_class_by(name):
    class Foo:
        pass
    class Bar:
        pass
    classes = {
        'foo': Foo,
        'bar': Bar
    }
    return classes.get(name, None)
for class_ in (get_class_by(name) for name in ('foo', 'bar', )):
    pprint(class_)
Explanation: you can pass it as a function parameter
End of explanation
print(type(1))
print(type("1"))
print(type(int))
print(type(ObjectCreator))
print(type(type))
Explanation: But it's not so dynamic, since you still have to write the whole class yourself.
Since classes are objects, they must be generated by something.
When you use the class keyword, Python creates this object automatically. But as with most things in Python, it gives you a way to do it manually.
Remember the function type? The good old function that lets you know what type an object is:
End of explanation
classes = Foo, Bar = [type(name, (), {}) for name in ('Foo', 'Bar')]
for class_ in classes:
    pprint(class_)
Explanation: Well, type has a completely different ability, it can also create classes on the fly. type can take the description of a class as parameters, and return a class.
End of explanation
classes_with_attributes = Foo, Bar = [type(name, (), namespace) 
                                      for name, namespace 
                                      in zip(
                                             ('Foo', 'Bar'), 
                                             (
                                              {'assigned_attr': 'foo_attr'}, 
                                              {'assigned_attr': 'bar_attr'}
                                             )
                                             )
                                      ]
for class_ in classes_with_attributes:
    pprint([item for item in vars(class_).items()])
Explanation: type accepts a dictionary to define the attributes of the class. So:
End of explanation
def an_added_function(self):
    return "I am an added function."
Foo.added = an_added_function
foo = Foo()
print(foo.added())
Explanation: Eventually you'll want to add methods to your class. Just define a function with the proper signature and assign it as an attribute.
End of explanation
%%HTML
<p style="color:red;font-size: 150%;">[Creating a class on the fly, dynamically] is what Python does when you use the keyword class, and it does so by using a metaclass.</p>
%%HTML
<p style="color:red;font-size: 150%;">Metaclasses are the 'stuff' that creates classes.</p>
Explanation: You see where we are going: in Python, classes are objects, and you can create a class on the fly, dynamically.
End of explanation
%%HTML
<p style="color:red;font-size: 150%;">Well, metaclasses are what create these objects. They are the classes' classes.</p>
%%HTML
<p style="color:red;font-size: 150%;">Everything, and I mean everything, is an object in Python. That includes ints, strings, functions and classes. All of them are objects. And all of them have been created from a class (which is also an object).</p>
Explanation: You define classes in order to create objects, right?
But we learned that Python classes are objects.
End of explanation
class MyType(type):
    pass
class MySpecialClass(metaclass=MyType):
    pass
msp = MySpecialClass()
type(msp)
type(MySpecialClass)
type(MyType)
Explanation: Changing to blog post entitled Python 3 OOP Part 5—Metaclasses
object, which inherits from nothing.
reminds me of Eastern teachings of 'sunyata': 
emptiness, voidness, openness, nonexistence, thusness, etc.
```python
a = 5
type(a)
<class 'int'>
a.class
<class 'int'>
a.class.bases
(<class 'object'>,)
object.bases
()  # object, which inherits from nothing.
type(a)
<class 'int'>
type(int)
<class 'type'>
type(float)
<class 'type'>
type(dict)
<class 'type'>
type(object)
<class 'type'>
type.bases
(<class 'object'>,)
```
When you think you grasped the type/object matter read this and start thinking again
```python
type(type)
<class 'type'>
```
End of explanation
%%HTML
<p style="color:red;font-size: 150%;">"Build a class"? This is a task for metaclasses. The following implementation comes from Python 3 Patterns, Recipes and Idioms.</p>
class Singleton(type):
    instance = None
    def __call__(cls, *args, **kwargs):
        if not cls.instance:
            cls.instance = super(Singleton, cls).__call__(*args, **kwargs)
        return cls.instance
class ASingleton(metaclass=Singleton):
    pass
a = ASingleton()
b = ASingleton()
print(a is b)
print(hex(id(a)))
print(hex(id(b)))
Explanation: Metaclasses are a very advanced topic in Python, but they have many practical uses. For example, by means of a custom metaclass you may log any time a class is instanced, which can be important for applications that shall keep a low memory usage or have to monitor it.
End of explanation
%%HTML
<p style="color:red;font-size: 150%;">The tasks of the two methods are very clear and distinct: __new__() shall perform actions needed when creating a new instance while __init__ deals with object initialization.</p>
class MyClass:
    def __new__(cls, *args, **kwargs):
        obj = super().__new__(cls, *args, **kwargs)
        # do something here
        obj.one = 1
        return obj  # instance of the container class, so __init__ is called
%%HTML
<p style="color:red;font-size: 150%;"> Anyway, __init__() will be called only if you return an instance of the container class. </p>
my_class = MyClass()
my_class.one
class MyInt:
    def __new__(cls, *args, **kwargs):
        obj = super().__new__(cls, *args, **kwargs)
        obj.join = ':'.join
        return obj
mi = MyInt()
print(mi.join(str(n) for n in range(10)))
Explanation: The constructor mechanism in Python is on the contrary very important, and it is implemented by two methods, instead of just one: new() and init().
End of explanation
class MyBool(int):
    def __repr__(self):
        return 'MyBool.' + ['False', 'True'][self]
t = MyBool(1)
t
bool(2) == 1
MyBool(2) == 1
%%HTML
<p style="color:red;font-size: 150%;">In many classes we use __init__ to mutate the newly constructed object, typically by storing or otherwise using the arguments to __init__. But we can’t do this with a subclass of int (or any other immuatable) because they are immutable.</p>
Explanation: Subclassing int
Object creation is behaviour. For most classes it is enough to provide a different __init__ method, but for immutable classes one often have to provide a different __new__ method.
In this subsection, as preparation for enumerated integers, we will start to code a subclass of int that behave like bool. We will start with string representation, which is fairly easy.
End of explanation
bool.__doc__
class NewBool(int):
    def __new__(cls, value):
        # bool 
        return int.__new__(cls, bool(value))
y = NewBool(56)
y == 1
Explanation: The solution to the problem is to use new. Here we will show that it works, and later we will explain elsewhere exactly what happens.
End of explanation
<END_TASK>