Repository: ManimCommunity/manim
Pull request: Implemented :meth:`.Mobject.set_default`, a mechanism for changing default values of keyword arguments
<!-- Thank you for contributing to Manim! Learn more about the process in our contributing guidelines: https://docs.manim.community/en/latest/contributing.html -->

## Overview: What does this pull request change?

There has been a lot of discussion about default values for Mobjects (I'll go through the list of issues and link the related ones in a bit). This is a very, very, *very*, simple (read: it is not particularly clever or involved) proposal which allows users to change the default values of the keyword arguments of a given class.

<!--changelog-start-->
This new feature allows to change the default value of keyword arguments passed to the constructor of mobjects.
For example, after running ``Text.set_default(color=BLACK)``, new texts like ``Text("Hello world!")``
will be colored black by default. See the documentation of :meth:`.Mobject.set_default` for more
details.
<!--changelog-end-->

## Motivation and Explanation: Why and how do your changes improve the library?
<!-- Optional for bugfixes, small enhancements, and documentation-related PRs. Otherwise, please give a short reasoning for your changes. -->

Changing default values is something very common, and it should be easy to do. Speaking from a big-picture point of view, there are two possible approaches: storing default values in a separate module (`config.defaults`?), or storing them in the mobject itself.

I like this proposed solution, because (a) it is rather simple (b) if we decide to add more infrastructure to default values (e.g., keeping track of values, allowing to save/restore configurations, whatever) the method-interface via `.change_default(**kwargs)` can be extended and appropriately modified easily without introducing breaking changes.

## Links to added or changed documentation pages
<!-- Please add links to the affected documentation pages (edit the description after opening the PR). The link to the documentation for your PR is https://manimce--####.org.readthedocs.build/en/####/, where #### represents the PR number. -->

https://manimce--2075.org.readthedocs.build/en/2075/reference/manim.mobject.mobject.Mobject.html#manim.mobject.mobject.Mobject.change_default


## Further Information and Comments
<!-- If applicable, put further comments for the reviewers here. -->



<!-- Thank you again for contributing! Do not modify the lines below, they are for reviewers. -->
## Reviewer Checklist
- [ ] The PR title is descriptive enough for the changelog, and the PR is labeled correctly
- [ ] If applicable: newly added non-private functions and classes have a docstring including a short summary and a PARAMETERS section
- [ ] If applicable: newly added functions and classes are tested


Problem statement:
Ability to set the default font
It should be possible to set a global default font, rather than having to explicitly set it in every `Text` object.

If that is already possible somehow then it should be documented, because I could figure it out even after reading the source code.

Hints from issue discussion:
We currently don't have a mechanism for setting/changing default values; but you can always create a custom subclass

```py
class MyText(Text):
    def __init__(self, *args, font=..., **kwargs):
        super().__init__(*args, font=font, **kwargs)
```

Also, feel free to join the discussion for a feature like that over at #2075.

Commit message: actually fix doctest 🙄

Patch to review:
diff --git a/manim/mobject/mobject.py b/manim/mobject/mobject.py
index c949793eb2..afeed5af84 100644
--- a/manim/mobject/mobject.py
+++ b/manim/mobject/mobject.py
@@ -11,7 +11,7 @@
 import sys
 import types
 import warnings
-from functools import reduce
+from functools import partialmethod, reduce
 from math import ceil
 from pathlib import Path
 from typing import (
@@ -180,6 +180,41 @@ def add_animation_override(
                 f"{override_func.__qualname__}.",
             )
 
+    @classmethod
+    def change_default(cls, **kwargs):
+        """Changes the default values of keyword arguments.
+
+        Parameters
+        ----------
+
+        kwargs
+            Passing any keyword argument will update the default
+            values of the keyword arguments of the initialization
+            function of this class.
+
+        Examples
+        --------
+
+        ::
+
+            >>> from manim import Square, GREEN
+            >>> Square.change_default(color=GREEN, fill_opacity=0.25)
+            >>> s = Square(); s.color, s.fill_opacity
+            (<Color #83C167>, 0.25)
+
+        .. manim:: ChangedDefaultTextcolor
+            :save_last_frame:
+
+            config.background_color = WHITE
+
+            class ChangedDefaultTextcolor(Scene):
+                def construct(self):
+                    Text.change_default(color=BLACK)
+                    self.add(Text("Changing default values is easy!"))
+
+        """
+        cls.__init__ = partialmethod(cls.__init__, **kwargs)
+
     @property
     def animate(self):
         """Used to animate the application of a method.


Code review comments:
diff_hunk: @@ -180,6 +180,41 @@ def add_animation_override(
                 f"{override_func.__qualname__}.",
             )
 
+    @classmethod
+    def change_default(cls, **kwargs):
+        """Changes the default values of keyword arguments.
+
+        Parameters
+        ----------
+
+        kwargs
+            Passing any keyword argument will update the default
+            values of the keyword arguments of the initialization
+            function of this class.
+
+        Examples
+        --------
+
+        ::
+
+            >>> from manim import Square, GREEN
+            >>> Square.change_default(color=GREEN, fill_opacity=0.25)
+            >>> s = Square(); s.color, s.fill_opacity
+            (<Color #83C167>, 0.25)
path: manim/mobject/mobject.py
text: @author:
```suggestion
            (<Color #83c167>, 0.25)
```