> For the complete documentation index, see [llms.txt](https://coding-girls-club.gitbook.io/python-turtle-tutorial/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://coding-girls-club.gitbook.io/python-turtle-tutorial/2-python-bian-cheng/2.4-ding-yi-lei-mi-gong/2.4.5-dui-xiang-de-chuang-jian-he-lei-de-chuang-jian.md).

# 2.4.5 对象的创建和类的创建

本节目标：

* 了解通过一个类创建对象的过程
* 了解类创建的过程

在`__init__`方法中，我们已经可以使用`self`了，也就是说，`__init__`的调用发生在对象创建之后。 但在Python中，我们有办法干预到对象创建本身。

**Learning By Reading 难度：★★ 重要性：★★★★★**

* 阅读材料，了解[`__new__`](https://foofish.net/magic-method.html)。

同时，类也是对象，因此我们也有办法创建类对象。

**Learning By Reading 难度：★★ 重要性：★★★**

* 阅读材料，了解[metaclass（元类）](http://wiki.jikexueyuan.com/project/explore-python/Class/metaclass.html)。

类也是对象，是一个`type`类型的对象，所以我们看到在创建类的时候我们用到了`type`类的`__new__`方法。 这一点，类和其他对象没有区别。

我们先来玩一玩`__new__`\~

```python
class MyTurtle(turtle.Turtle):

    _all_turtles = {}

    def __init__(self, name, *args, **kwargs):
        self.name = name
        MyTurtle._all_turtles[name] = self

    @classmethod
    def get_by_name(cls, name):
        return cls._all_turtles[name]

ada = MyTurtle('ada')
if MyTurtle.get_by_name('ada') == ada:
    print("找到了ada") # 输出

ada2 = MyTurtle('ada')
if MyTurtle.get_by_name('ada') == ada2:
    print("又找到了ada") # 输出

if ada == ada2:
    print("两只一样的ada") # 不输出
```

大家想一下就发现，`ada = MyTurtle('ada')`和`ada2 = MyTurtle('ada')`虽然都是创建了名字是`ada`的小海龟， 但是只是名字相同，并不是真的是同一只。并且后一只会在`MyTurtle._all_turtles`里面覆盖掉前面一只。

如果想要让每次`MyTurtle('ada')`的时候都得到同一只小海龟应该怎么做呢？

```python
class MyTurtle(turtle.Turtle):

    _all_turtles = {}

    def __new__(cls, name, *args, **kwargs):
        if name not in cls._all_turtles:
            cls._all_turtles[name] = super(MyTurtle).__new__(*args, **kwargs)
        return cls._all_turtles[name]

    def __init__(self, name):
        self.name = name

ada = MyTurtle('ada')
ada2 = MyTurtle('ada')
if ada == ada2:
    print("两只一样的ada") # 输出
```

`__new__`告诉Python如何创建`MyTurtle`类的对象， `ada = MyTurtle('ada')`的时候，Python发现`ada`这个名字不在`MyTurtle._all_turtles`里面，于是返回了一个新创建的海龟对象（用`super(MyTurtle).__new__`）。 `ada2 = MyTurtle('ada')`的时候，就直接返回储存在`MyTurtle._all_turtles`中的`ada`了。

我们之前介绍过，Python中的类也是对象，每个类都是`type`对象。 `type`类就是用来创建类对象的，也是通过`__new__`方法。

```python
class MyTurtle(turtle.Turtle, AnotherClass, AnotherAnotherClass):

    _all_turtles = {}

    def __init__(self, name):
        self.name = name
```

这样定义一个类，等价于

```python
def __init__(self, name):
    self.name = name

MyTurtle = type('MyTurtle', (turtle.Turtle, AnotherClass, AnotherAnotherClass), {'_all_turtles': {}, '__init__': __init__})
```

后一种方法直接用`type`类生成了一个类。 我们看到`type`带了三个参数，第一个是一个字符串表示类名，第二个是一个`tuple`表示继承哪些类，第三个是一个字典表示所有的属性和方法。
